Durzan
Durzan

Reputation: 23

How to get a JSON object of all files and folder structure

I tried to build a function with Cordova which gives me a JSON object that looks as follows:

{
  "file:///storage/emulated/0/Android/data/test/files/data/bla.txt": "bla.txt",
  "file:///storage/emulated/0/Android/data/test/files/data/HelloWorld.txt": "HelloWorld.txt",
  "file:///storage/emulated/0/Android/data/test/files/data/RSC/picture-1469199158993.jpg": "picture-1469199158993.jpg",
  "file:///storage/emulated/0/Android/data/test/files/data/RSC/picture-1469199665434.jpg": "picture-1469199665434.jpg",
  "file:///storage/emulated/0/Android/data/test/files/data/API-Test/test/datFile.txt": "datFile.txt",
  "file:///storage/emulated/0/Android/data/test/files/data/RSC/thumbnails/picture-1469199158993.jpg": "picture-1469199158993.jpg",
  "file:///storage/emulated/0/Android/data/test/files/data/RSC/thumbnails/picture-1469199665434.jpg": "picture-1469199665434.jpg"
}

My problem is that the Cordova functions are async so my function returns an empty object.

Here is my solution so far:

var dirObj = new Object();

function getFiles(fullPath, callback){
    dirObj = new Object();

    window.resolveLocalFileSystemURL(fullPath, addFileEntry, function(e){
            console.error(e);
    });

    return JSON.stringify(dirObj);    
}

var addFileEntry = function (entry) {
  var dirReader = entry.createReader();
  dirReader.readEntries(
    function (entries) {
      var fileStr = "";
      for (var i = 0; i < entries.length; i++) {
        if (entries[i].isDirectory === true) {
          addFileEntry(entries[i]);
        } else {
          dirObj[entries[i].nativeURL] = entries[i].name;
          console.log(entries[i].fullPath);
        }
      }
    },
    function (error) {
      console.error("readEntries error: " + error.code);
    }
  );
};

Note: Promise() is not an option because the function have to work on Chrome 30.0 and Promise() is avaible since 32.0 (src).

Upvotes: 1

Views: 2046

Answers (2)

AxelH
AxelH

Reputation: 14572

var dirObj;

function getFiles(fullPath, callback){
    dirObj = new Object();

    window.resolveLocalFileSystemURL(fullPath, addFileEntry, function(e){
            console.error(e);
    });
}

var counter = 0;

var addFileEntry = function (entry) {
  ++counter;
  var dirReader = entry.createReader();
  [...] //you probably should do it in the readEntries function to since this is async to (as you said), because this could still run while the following line might be executed. If so, just add the same if(...) callback();
  if(--counter == 0)
      callBack();
};

function callBack(){
   var json = JSON.stringify(dirObj);
   //Do what you need with it.
}

Upvotes: 0

Durzan
Durzan

Reputation: 23

I found a solution similar to @AxelH suggested solution. I used an array: Everytime I called the function addFileEntry I pushed a id into the array. When the function was finished I removed the id from the array. I called then the callback function if the array is empty.

Thank you @AxelH for your help and thanks @gcampbell for mentioning bluebird which I didn't know and will use for an other async problem in javascript.

Upvotes: 0

Related Questions