0

I am just getting started with coding for FirefoxOS and am trying to get a list of files in a directory.

The idea is to find the name of each file and add it to the array (which works), but I want to return the populated array and this is where I come unstuck. It seems that the array gets populated during the function (as I can get it to spit out file names from it) but when I want to return it to another function it appears to be empty?

Here is the function in question:

    function getImageFromDevice (){
    var imageHolder = new Array();  
    var pics = navigator.getDeviceStorage('pictures');

    // Let's browse all the images available
    var cursor = pics.enumerate();
    var imageList = new Array();
    var count = 0;

    cursor.onsuccess = function () {
    var file = this.result;

    console.log("File found: " + file.name);

    count = count +1;

      // Once we found a file we check if there are other results
      if (!this.done) {

    imageHolder[count] = file.name;

        // Then we move to the next result, which call the cursor
        // success with the next file as result.
        this.continue();

      } 
      console.log("file in array: "+ imageHolder[count]);
              // this shows the filename        
              }

    cursor.onerror = function () {
      console.warn("No file found: " + this.error);
    }


            return imageHolder;     
            }

Thanks for your help!

SeekTom
  • 296
  • 1
  • 5

2 Answers2

2

Enumerating over pictures is an asynchronous call. Essentially what is happening in your code is this:

  1. You are initiating an empty array

  2. You are are telling firefox os to look for pictures on the device

  3. Then in cursor.onsuccess you are telling firefox os to append to the array you have created WHEN it gets back the file. The important thing here is that this does not happen right away, it happens at some point in the future.

  4. Then you are returning the empty array you have created. It's empty because the onsuccess function hasn't actually happened.

After some point in time the onsuccess function will be called. One way to wait until the array is full populated would be to add in a check after:

if (!this.done) {
    imageHolder[count] = file.name;
    this.continue();
} 
else {
    //do something with the fully populated array
}

But then of course your code has to go inside the getImageFromDevice function. You can also pass a callback function into the getImageFromDevice function.

See Getting a better understanding of callback functions in JavaScript

Community
  • 1
  • 1
Bob
  • 189
  • 6
0

The problem is with the aSynchronous nature of the calls you are using.

You are returning (and probably using) the value of imageHolder when it's still empty - as calls to the "onsuccess" function are deferred calls, they happen later in time, whereas your function returns immediately, with the (yet empty) imageHolder value.

You should be doing in this case something along those lines:

function getImageFromDevice (callback){

  ...

  cursor.onsuccess = function () {
    ...

    if (!this.done) {

      // next picture
      imageHolder[count] = file.name;
      this.continue();

    } else {

      // no more pictures, return with the results
      console.log("operation finished:");
      callback(imageHolder);

    }
  }

}

Or use Promises in your code to accomplish the same.

Use the above by e.g.:

getImageFromDevice(function(result) {
  console.log(result.length+" pictures found!");
});
Flaki
  • 578
  • 2
  • 6