I have a feeling that this is a very basic error, but I've spent a couple of days reading articles/books about scope in JavaScript, returning to this problem, and still not really achieving any clarity, let alone a working solution – so its time to throw myself upon your mercy. I've looked at the other questions/answers, of course, but they seem to be referring to different kinds of scope problems, or at least studying them hasn't brought me any closer to a solution, so I though I'd risk asking for myself.
This function is supposed to take a list of filenames, then iterate over the list retrieving the files themselves and passing the contents to another function, which itself returns a javascript object representing the file content. As noted in the comments, this method itself works – when articles[i] is created inside the loop, articles[i].body contains exactly the data it should. But, by the time the loop is finished, somehow the array is empty again. Is anyone able to tell me what I've done wrong?
// Returns an array of processed article objects
function processAllArticles(dirname, res) {
fs.readdir(dirname, function(err, filenames) {
if (err) {
onError(err);
return;
}
var articles = []; // I think this is in the wrong scope?
// Array.foreach is 95% slower than a regular for loop apparently
for (var i = 0, len = filenames.length; i < len; i++) {
//console.log(filenames[i]); // This part seems to work
var currentFilePath = dirname + '/' + filenames[i];
//console.log("Trying to pass in " + currentFilePath);
fs.readFile(currentFilePath, function(err, content) {
articles[i] = processArticle(content)
// The article object seems to exist in here
// console.log(articles[i].body);
});
console.log("Articles array after iteration = " + articles); //Empty
console.log("Articles["+ i + "] = " + articles[i]); // Undefined.
} // end loop
console.log("ready to render " + articles.length + " article objects.");
// articles is empty at this point ugh so nothing is being rendered
res.render('index', { articles: articles });
});
}