I have an ajax call that is inside a forEach loop which is inside another function. The problem is, that the callback of the outer function fires before the inner loop ends - so "staticItemList" is not filled with the items when passed to the callback. How can I fix that ? I really spent a lot of hours on that. Thanks.
exports.buildTheList = function (parsedList, callback) {
var staticItemList = {};
parsedList.forEach(function(parsedItem) {
db.staticList.find({"_id":parsedItem.ID}).forEach(function(err, doc) {
if (!doc){
console.log("newStaticItem not found in db");
parsedDataFetcher.fetchParsedDetails(Path, function(parsedDetails){
staticItemList["_id"] = parsedItem.ID;
staticItemList[parsedItem.ID] = {
"_id": parsedItem.ID,
"type": parsedItem.type,
}
})
}else {
console.log("newStaticItem already found in db");
}
});
});
callback(staticItemList);
}
Add a counter variable inside the loop, and decrement it every time the async methods complete. Once the counter hits zero, call callback. In pseudo-code:
var counter = 0;
foreach(function() {
counter++;
doAsync(function() {
// add to list
counter--;
if (counter === 0) {
callback(list);
}
});
}
Hope that helps.
I'd look at something like dojo promise all
. From the manual:
dojo/promise/all
is a function that takes multiple promises and returns a new promise that is fulfilled when all promises have been fulfilled.
The examples on that page demonstrate how you can do what you need.
AJAX occurs asynchronously, so what happens is your loops runs, triggering all the AJAX calls, and then completes, calling your callback. You will likely need to implement some sort of counter in your foreach loop and check that on completion of each AJAX call. one the number of completed AJAX calls is the same as the number of the counter, you would execute your callback function from within the asynchronous function context.