One way, would be to attach a .catch handler indidually in your service:
function asyncCall(urls){
var calls = urls.map(makeSomeCall).
map(function(prom){ return prom.catch(e){ /* recover here */});
return $q.all(calls);
};
Another way would be to implement a settle method that is like $q.all but keeps track of all results. Stealing from my answer here:
function settle(promises){
var d = $q.defer();
var counter = 0;
var results = Array(promises.length);
promises.forEach(function(p,i){
p.then(function(v){ // add as fulfilled
results[i] = {state:"fulfilled", promise : p, value: v};
}).catch(function(r){ // add as rejected
results[i] = {state:"rejected", promise : p, reason: r};
}).finally(function(){ // when any promises resolved or failed
counter++; // notify the counter
if (counter === promises.length) {
d.resolve(results); // resolve the deferred.
}
});
});
})
You can handle multiple promises as such:
var promiseArr = ["id0","id3","id2"].map(makePromise);
settle(promiseArr).then(function(results){
var failed = results.filter(function(r){ return r.state === "rejected"; });
var failedValues = failed.map(function(i){ return i.value; });
var done = results.filter(function(r){ return r.state === "fulfilled"; });
var doneValues = done.map(function(i){ return i.value; });
});
Which gives you access to all results of the promise, regardless if it failed or not, and let you recover with more granularity.
Your service should handle that aggregation since it's the one returning a promise on everything. One example would be to do:
if(failed.length > 0){
throw new Error("The following failed..."); // some info about all failed
}
$q.allgets rejected when any of the promises gets rejected. What exactly are you trying to achieve ?$q.all$q.all. I want myasyncCall1. to get array of promises, 2. has one resolve handler for each resolved promise from the array (thenblock from the example) 3. has one reject handler that will be called for each rejected promise. (catchblock from the example). I hope now it is clear.