function(response) part II

Started by JohnZeman, November 14, 2017, 07:52:34 PM

Previous topic - Next topic

JohnZeman

I'm back with another I haven't been able to figure this out yet question.  :o
I'm working on an app that when I push a button will move all of the files assigned to one specific category to a one specific folder.

I've got the first and last sections of it working, but it's the middle that has me stumped.  How do I hand off the file IDs assigned to the category, to the v1/files/move endpoint so those files can be moved?  I'm assuming it has to be in the form of an array.

Below is the main part of the script, and I'm also assuming I need to replace the ? in

idlist: ?,

With something else.  What?

Thanks again for any help guys.


         $('#btn-test').click(function() {
            IMWS.get('v1/categories', {
               path: '!Queue Filter|2017',
               fields: 'files',
            }).then(function(response) {
               console.log(JSON.stringify(response, null, 2));

               // begin move
                  IMWS.post('v1/files/move', {
                     scope: 'files',
                     idlist: ?,
                     replace: 'replaceifolder',
                     targetpath: 'D:\\Mine\\Photos\Keepers\\2010-2019\\2017'
                  }).then(function(response) {
                    console.log(JSON.stringify(response, null, 2));
                     },
                     function(error) {
                        resultInfo.text("ERROR!  The file could not be moved.");
                     });
               // end move
            });
         });

Mario

#1
You cannot use idlist here.
You either need to use one of the pre-defined idlists (fileWindowSelection) or you need to create your own idlist first.

To hand over the ids of the files assigned to your category you would instead just use the id parameter.
It takes a list of one or more ids, separated by ,

Assuming that response.files contains an array of ids: [1,2,3,4,100] this does the trick:

id: response.files.join(',')

the join method of an array produces a string from the elements of the array, using the specified character to separate them.

[1,2,3,4,100] will be converted to '1,2,3,4,100' which is exactly what you need.

Tip: You can try out such things directly in the console in your browser (Chrome in this case):



Type in the first row then press <Enter> to see the result. A quick way to try such things out.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

JohnZeman

Thanks Mario.
This is going to take some thinking on my part but I'm going to have to shelve this project for a week or so because we're about to take a little road trip.
Can't miss my youngest granddaughter's third birthday party ya know. :)

JohnZeman

I'm revisiting this issue again and I'm totally stumped at why I constantly get the following error when push the test button.

jquery.min.js:2 jQuery.Deferred exception: Cannot read property 'join' of undefined TypeError: Cannot read property 'join' of undefined
    at Object.<anonymous> (http://127.0.0.1:50519/user/Test/index.html:72:31)
    at j (http://127.0.0.1:50519/system/jquery/dist/jquery.min.js:2:29948)
    at k (http://127.0.0.1:50519/system/jquery/dist/jquery.min.js:2:30262) undefined


Basically I want to move all files in the !Queue Filter|2017 category to a specific folder.

Below is the script code I've been trying to use.


         $('#btn-test').click(function() {

            IMWS.get('v1/categories', {
               path: '!Queue Filter|2017',
               fields: 'files',
            }).then(function(response) {
               var matches = [];
               matches = response.files;

               // begin move
               IMWS.post('v1/files/move', {
                  scope: 'files',
                  id: matches.join(','),
                  replace: 'replaceifolder',
                  targetpath: 'D:\\Mine\\Photos\Keepers\\2010-2019\\2017'
               }).then(function(response) {
                     console.log(JSON.stringify(response, null, 2));
                  },
                  function(error) {
                     resultInfo.text("ERROR!  The file could not be moved.");
                  });
               // end move

            });
         });


Anyone see what I'm doing wrong here?

Mario

Javascript complains that you use join on an undefined variable in line 72 of your script.

I guess

matches = response.files;

fails because the category endpoint does not return an array named files.
response.files is undefined and hence matches will become undefined. And then the later join fails.

The endpoint returns a list of categories (all you have requested) and for each category it returns the requested fields.

Did you  look in the debugger of your web browser to see what response really contains?
It will look like

categories : [
...
]

an array of categories. And each element in this array contains the data you have requested.

Take out the guesswork. Use the debugger in your browser to see what IMWS has returned.

-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

JohnZeman

Thanks for the quick response Mario.
I've been trying to figure out how to use the Chrome debugger, the error message I posted last time came from...well I'll just post a screenshot of what I'm seeing.

JohnZeman

This is what I'm seeing.  I have 3 test files in the category so it looks right to me.

{
  "categories": [
    {
      "files": [
        74827,
        74828,
        74829
      ]
    }
  ]
}

thrinn

The error message you see means that matches is not defined. Because you set matches to response.files some lines before, this translates to "response does not have a property 'files'".

One thing to keep in mind: response objects are often deeply nested: the response object has a property categories. The value (singular!) of this property is an array. Each element of this array is again an object that has a property named files. The value of this property is, again, an array. This is exactly what you screenshot shows.
Therefore, if you want to access some property, check carefully if you are trying to access the right object (instead of some "outer" object...). Are you using the right number of dots and array indizes to get to the nesting level you want to access?

JavaScript, the language of bracket counting...
Thorsten
Win 10 / 64, IMatch 2018, IMA

Mario

Quote from: JohnZeman on November 27, 2017, 12:40:52 AM
This is what I'm seeing.  I have 3 test files in the category so it looks right to me.

{
  "categories": [
    {
      "files": [
        74827,
        74828,
        74829
      ]
    }
  ]
}


This looks great. Your endpoint call returned data for one category.
To access the first (and only) returned category object you use

response.categories[0]

Each category object has an array named files which holds the data you requested for each file.
Usually this is another object wrapped in { and } - except you have only requested the file ids. In this case IMWS performs an optimization and returns an array of file ids instead of an object for each file. This reduces packet size and network traffic.

response.categories[0].files.forEach(f => {
  console.log(f);
});

outputs the id of each file to the console.



-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

Carlo Didier

Quote from: thrinn on November 27, 2017, 07:27:23 AMJavaScript, the language of bracket counting...
:) Ever heard of Lisp?
https://www.tutorialspoint.com/lisp/

I had some fun with that many years ago (did some programming in AutoCAD).

JohnZeman

Ah, the lights finally came on, thanks guys!!!

If anyone else is trying to do something similar below is the code that actually works.  It still needs a little cleanup work but hey, it does work. :)

Now I can finish my automatic file mover app to move all newly imported files to the appropriate destination folder automatically. :) :) :)


         $('#btn-test').click(function() {

            var DestFolder = "D:\\Mine\\Photos\\Keepers\\2010-2019\\2017"; // Folder to move files to
            var CatToCheck = "!Queue Filter|2017"; // Category to check for files

            IMWS.get('v1/categories', {
               path: CatToCheck,
               fields: 'files,filescount',
            }).then(function(response) {
               var matches = []; // Create an empty array
               matches = response.categories[0].files; // Get the response that tells the IDs of the files in this category
               var FilesToMove = response.categories[0].filesCount; // Get number of files in this category

               var ResultMsg = "";
               if (FilesToMove == 0) {
                  ResultMsg = "No files in " + CatToCheck + " to move";
                  resultInfo.text(ResultMsg);
                  return;
               } else if (FilesToMove == 1) {
                  ResultMsg = FilesToMove + " file was moved to " + DestFolder;
               } else {
                  ResultMsg = FilesToMove + " files were moved to " + DestFolder;
               }

               // begin move
               IMWS.post('v1/files/move', {
                  scope: 'files',
                  id: matches.join(','),
                  targetpath: DestFolder,
               }).then(function(response) {
                     resultInfo.text(ResultMsg);
                  },
                  function(error) {
                     resultInfo.text("ERROR!  Files could not be moved.");
                  });
               // end move

            });
         });

thrinn

Quote:) Ever heard of Lisp?
Heard of: Yes.
Used it: No, never  :D
Thorsten
Win 10 / 64, IMatch 2018, IMA

Jingo

Quote from: thrinn on November 27, 2017, 09:16:04 PM
Quote:) Ever heard of Lisp?
Heard of: Yes.
Used it: No, never  :D

Used LISP over 27 years ago for my Comp Sci - Intro to Artificial Intelligence course...  much preferred the more complex go-to language of the day... Pascal!  Now there is a computer language I thoroughly enjoyed... I still remember programming double-linked lists for memory storage/retrieval.... oh the memories!!

Carlo Didier

Quote from: Jingo on November 27, 2017, 09:29:15 PM...  much preferred the more complex go-to language of the day... Pascal!
Me too. Pascal was just awesome. Did some big stuff in Turbo Pascal on CP/M back then. For a Cement plant.

Jingo

#14
Also used Turbo Pascal on a MS-dos box the size of fridge at college... remember getting new machines that did 16 colors.. everyone was amazed!  Gosh - I sound like my grandparents.... guess it really does happen when you get older!   :o