Reputation: 13
I want to make an initial request to get a list of IDs, and then make a request for each individual id and store the JSON results in an array. Here is the code basics:
request(options, function(err, resp, body){
ids = (JSON.parse(body))[ids];
results=[];
for(id in ids){
options.path='/api/example/' + ids[id];
request(options, function(err, resp, body){
results.push(JSON.parse(body));
})
}
res.send(results);
})
When I run this, results is still an empty array and when I put res.send(results) in the inner request function,it only captures one result and not all of them. Any ideas?
Upvotes: 0
Views: 78
Reputation: 64933
Most NodeJS operations are asynchronous. If some function requires a callback it means that there's no guarantee that after invoking it you'll get the result.
When you perform N requests using the for
loop you're starting N asynchronous operations and each one's callback will be called when the underlying asynchronous operation has ended.
There're many options here to solve the issue.
For example, you can use Q, a Promise pattern implementation, to enqueue async promises and wait untill all have been resolved:
request(options, function(err, resp, body){
// First of all, you create a deferred object
var deferred = Q.defer();
// Also, you create an array to push promises
var promises = [];
ids = (JSON.parse(body))[ids];
results=[];
for(id in ids){
options.path='/api/example/' + ids[id];
// You create a promise reference, and later
// you add it to the promise array
var promise = deferred.promise;
promises.push(promise);
request(options, function(err, resp, body){
results.push(JSON.parse(body));
// whenever an async operation ends, you resolve its promise
deferred.resolve();
})
}
// Now you wait to get all promises resolved (i.e. *done*), and then your
// "results" array will be filled with the expected results!
Q.all(promises).then(function() {
res.send(results);
});
});
Upvotes: 1