0

In a Chrome extension im using the HTML5 FileSytem API.

Im retrieving a list of records in a folder.

var entries = [];
var metadata = [];
listFiles(folder);

function listFiles(fs) {

    var dirReader = fs.createReader();
    entries = [];

    // Call the reader.readEntries() until no more results are returned.
    var readEntries = function () {
        dirReader.readEntries(function (results) {
            if (!results.length) {
                addMeta(entries);
            } else {
                console.log(results);
                entries = entries.concat(toArray(results));
                readEntries();
            }
        });
    };

    readEntries(); // Start reading dirs.

}

The FileEntry object does not contain metadata, I need the last modified date. I'm able to retrieve a object of metadata

    function addMeta(entries) {
    for (var i = 0; i < entries.length; i++) {
        entries[i].getMetadata(function (metadata) {
            console.log(entries);
            console.log(metadata);
        });
    }
}

Problem is that i get the metadata in a callback. How can i join the two object making sure the right match is made? The simplified result im looking for is:

[
["fileName1", "modifyDate1"],
["fileName2", "modifyDate2"],
]
Arnoud Kooi
  • 1,588
  • 4
  • 17
  • 25

2 Answers2

2
  1. To get lastModifiedDate, you don't need to use getMetadata, as per the description of this question, just use entry.file.lastModifiedDate, though maybe file() is another callback.
  2. To "join the two object making sure the right match is made", because of Closures, you could use the following code to get the right results. (Assuming the data structure is [[entry, metadata]] as you mentioned)

    var ans = [];
    function addMeta(entries) {
        for (var i = 0; i < entries.length; i++) {
            (function(entry) {
                entry.getMetadata(function (metadata) {
                    ans.push([entry, metadata]);
                });
            }(entries[i]);
        }
    }
    
  3. If what you want is to wait for all asynchronous callback ends, see this answer for more details, basically you could adjust your code and use Promise, or use other implementations like setInterval or use a variable to calculate how many callbacks remain.
Community
  • 1
  • 1
Haibara Ai
  • 10,703
  • 2
  • 31
  • 47
  • file also is a callback, but it contains both filename and modified date :), so no joining is needed! Thanks for elaborating on closures, i might need this concept soon! – Arnoud Kooi May 16 '16 at 10:16
0

I suggest to have a look on Promise-based bro-fs implementation of HTML Filesystem API.
To read all entries with metadata you can do something like this:

fs.readdir('dir')
  .then(entries => {
    const tasks = entries.map(entry => fs.stat(entry.fullPath))
    return Promise.all(tasks);
  })
  .then(results => console.log(results)) 
vitalets
  • 4,675
  • 1
  • 35
  • 35