javascriptcordovacordova-plugins

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).


Solution

  • 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.
    }