Accepted answer is okay, but is still a bit ugly. You have an array of things you want to send.. instead of using a for
loop, why not use Array.prototype.map
?
var data = ["data1","data2","data3"..."data10"];
for(var i=0;i<data.length;i++){
$http.get("http://example.com/"+data[i]).success(function(data){
console.log("success");
}).error(function(){
console.log("error");
});
}
This becomes
var data = ['data1', 'data2', 'data3', ...., 'data10']
var promises = data.map(function(datum) {
return $http.get('http://example.com/' + datum)
})
var taskCompletion = $q.all(promises)
// Usually, you would want to return taskCompletion at this point,
// but for sake of example
taskCompletion.then(function(responses) {
responses.forEach(function(response) {
console.log(response)
})
})
This uses a higher order function so you don't have to use a for
loop, looks a lot easier on the eyes as well. Otherwise, it behaves the same as the other examples posted, so this is a purely aesthetical change.
One word of warning on success
vs error
- success
and error
are more like callbacks and are warnings that you don't know how a promise works / aren't using it correctly. Promises then
and catch
will chain and return a new promise encapsulating the chain thus far, which is very beneficial. In addition, using success
and error
(anywhere else other than the call site of $http
) is a smell, because it means you're relying explicitly on a Angular HTTP promise rather than any A+ compliant promise.
In other words, try not to use success
/error
- there is rarely a reason for them and they almost always indicate a code smell because they introduce side effects.
With regards to your comment:
I have did my own very simple experiment on $q.all. But it only trigger when all request is success. If one if it fail, nothing happen.
This is because the contract of all
is that it either resolves if every promise was a success, or rejects if at least one was a failure.
Unfortunately, Angular's built in $q
service only has all
; if you want to have rejected promises not cause the resultant promise to reject, then you will need to use allSettled
, which is present in most major promise libraries (like Bluebird and the original Q
by kriskowal). The other alternative is to roll your own (but I would suggest Bluebird).
$q
service and specifcally$q.all
. – Kanzu$q.all
. But it only trigger when all request is success. If one if it fail, nothing happen. – Hummockyall
. If you want to have the aggregate promise resolve even if a child promise is rejected, you will need to look into usingallSettled
. Unfortunately, this method isn't in Angular's$q
library, but it is in the big-name libraries for Promises, like Bluebird. – Esmond