Reputation: 2494
I have an array of ids and would like to iterate over them and pass them to a service to fetch some data. But I would like to only move to the next id after the processing of the previous id has finished. After all the data has been fetched I need to call a specific function.
My code (without the iteration) wold be something like
MyService.fetch(id)
.success(function (data, status, headers, config) {
doSomething();
});
What I want to achieve is something like this but in a way which can handle an unknown number of items in my array of ids:
MyService.fetch(id).success(function (data, status, headers, config)
{
MyService.fetch(id2).success(function (data, status, headers, config)
{
doSomething();
});
});
Any ideas how to achieve this ?
thanks
Thomas
Upvotes: 1
Views: 95
Reputation: 7926
Angular comes with a lite promise library: $q. It's actually quite simple to do.
Service
myApp.factory('theProcessor', function($q, $timeout) {
return {
fetch: function(queue, results, defer) {
defer = defer || $q.defer();
var self = this;
// Continue fetching if we still have ids left
if(queue.length) {
var id = queue.shift();
// Replace this with your http call
$timeout(function() {
// Don't forget to call d.resolve, if you add logic here
// that decides not to continue the process loop.
self.fetch(queue, results, defer);
results.push({ id: id, value: Math.floor((Math.random()*100)+1) });
}, 500);
} else {
// We're done -- inform our caller
defer.resolve(results);
}
// Return the promise which we will resolve when we're done
return defer.promise;
},
};
});
See it in action at this plunker.
Upvotes: 3
Reputation: 1335
You could use the $q
's all()
method to bundle all the promises that you define and then do something after all of them are resolved e.g:
$q.all([promise1, promise2, ...]).then(...)
You may want to consider implementing this feature in your controller or your service.
Take a look at HERE for a complete API reference and details.
UPDATE
Just thinking that your service could accept an array of ids and it could have a method which would recursively fetch the data in order that you want. Look and the following code, it's an idea so it may not work as is:
function(){
var result = [];
var fetch = function(idArr /*this is your ID array*/){
(a simple guess if what you want to do with that ID)
$http.get('yourURL?id=' + <first element of idArr>)
.success(function(data){
//some logic
result.push(data);
idArr.splice(1,0);
fetch(idArr);
});
}
}
Upvotes: 1
Reputation:
Try to use following approuch:
var idsArray= [], result = [];
/// ...After filling array
function nextIteration(index) {
MyService.fetch(idsArray[index]).success(function (data, status, headers, config)
{
result.push(data);
if (++index < idsArray.length) {
nextIteration(index)
} else {
console.log('Task complete');
}
}
nextIteration(0);
Upvotes: 2