0

I am creating a browser-tool that is running on Chrome WebServer AddOn. The server offers a directory file listing by using GETrequest returning in a JSON array (incl. isFolder/isFile/filename values)

I have a list of folders that I need to scan for all files in this folder, including all subdirectories that should be returned in pushArray.

Now usually I would use a recursive function to iterate through this. As I am using $.get I have an asynchronous request and I have no idea how to iterate through then and return a list of all files. I tried around with .when().done() but I think am just lacking the idea how to do it instead of recursion.

The following code is not working and I understand why but what I have done so far:

function recursiveFileRead(data, pushArray) {
  var val = data; //data contains 
  val = String(val).trim() + "?json=1" //required so the server gives back the json object

  //get list of files and folder in a json object (async!)
  var callBack = $.get(val, function(val) {
    json = val;

    //loop through json object. 
    $.each(json, function(i, value) {
      //if file push to array
      if(value.isFile) {
        pushArray(value.filename);
      } else {
      //if folder recursively run through the subfolders
        recursiveFileRead(data, pushArray)
      };
    });
  });

  $.when( callBack() ).done(function() {
    //return pushArray
  });

}

After the array contains all files listed, I need to perform an action to ZIP those files. I guess I won't be able to do this synchronous, but if I iterate asynchronously how do I even know when I am finished?

Thanks a lot!

gerd hübner
  • 423
  • 3
  • 14

1 Answers1

0

So I have a (very bad) workaround. I am still not able to pass a variable "recursively" (so that I am adding the new data to one array) so I used a global variable. Also I don't manage to fire when all promises have been resolved so I am currently using a timer. At least I get the data I want, but any help is appreciated:

First in my "regular code" I am looping throug a list containing files/folders to check for folders. If there is a folder, I am calling the "recursive" async function:

  //go through items listed and check if file/folder
  $.each(data, function(i, value) {
    //get file ending
    var extn = value.split(".").pop();

    //use array defined before to check
    if (validFormats.indexOf(extn) == -1) {
      console.log("folder: " + value);
      //folder - start recursive directory list
      promises.push(requestAll(value));
    } else {
      pushArray.push(value);
      console.log("file: " + value);
    }
  });

  console.log(promises); //<= logs the promises
  $.when.apply($, promises).done(function(responses) {
    alert("done"); //<= doesn't fire
    console.log(responses);
  });

  setTimeout(function() {
    alert(pushArrayGlobal.join("\n"))
  }, 3000);

As you can see in the comments, the when.apply.done for the promises is not fireing, the timeout does and I get a full list of the data I need.

The following code for listing the files "recursively" is based on https://stackoverflow.com/a/23355670/4178195

function request(data) {
  // return the AJAX promise
  return $.ajax({
    url: data + '/?json=1',
    method: 'GET',
    dataType: 'json'
  });
}


function requestOddsFrom(folder, items) {

  return request(folder).then(function(data) {
    $.each(data, function(i, value) {
      console.log(value);
      var newArray = [];
      console.log(value.name);
      //if folder
      if (value.isDirectory) {
        //remove first folder of relative path and call request again
        requestOddsFrom(value.fullPath.split('/').slice(2).join('/'), []);
      //if file add to pushArrayGlobal
      } else {
        pushArrayGlobal.push(value.fullPath);
      }
    });
  });
}

function requestAll(data) {
  return $.Deferred(function() {
    var self = this;
    $.when(requestOddsFrom(data, [])).then(function(items) {
      self.resolve(pushArrayGlobal);
    });
  });
}
Community
  • 1
  • 1
gerd hübner
  • 423
  • 3
  • 14