JomsDev
JomsDev

Reputation: 116

$q.all() in angular does not resolve well

I am doing 3 $http calls in a factory and I am in troubles.

I declare 4 promises:

var promise = $q.defer(),
  PBdeferred = $q.defer(),
  Rdeferred = $q.defer(),
  Pdeferred = $q.defer();

After that I do the first call to the API

$http.get('/pendingBills').then(function(response) {
  var PendingBills = ['id', 'path', 'reservas', 'importe', 'fecha'];
  PBdeferred.resolve(PendingBills);
});

And for now resolve the last 2 promises with an empty array (I have not the endopoint yet)

  Rdeferred.resolve([]);
  Pdeferred.resolve([]);

There is where I use $q.all

$q.all([PBdeferred, Rdeferred, Pdeferred]).then(function (results){
    console.log('Results', results);
    promise.resolve({
      PendingBills: results[0],
      Remittances: results[1],
      Payed: results[2]
    });
  });

And return the higth level promise

return promise.promise;

The console log shows the promises but I thougth that in there point the promises are resolved.

Some idea for fix this?

Upvotes: 3

Views: 3207

Answers (2)

Ori Drori
Ori Drori

Reputation: 192467

You are not using promises correctly, as you use deferred which is an anti pattern that breaks the promises chain. Instead of using deferred, just get the promise for each of your actions, then combine them using $q:

var PBpromise = $http.get('/pendingBills').then(function(response) {
  return ['id', 'path', 'reservas', 'importe', 'fecha']; // this will return a promise with the array as the resolve value
});

var Rpromise = $q.resolve(); // a promise that is resolved immediately. Later you can replace it with the $http call 

var Ppromise = $q.resolve(); // a promise that is resolved immediately. Later you can replace it with the $http call 

var promise = $q.all([PBdpromise, Rpromise, Ppromise]).then(function (results){ // $q.all also returns a promise
    console.log('Results', results);
    return { // this will be the resolve value of the returned $q promise
      PendingBills: results[0],
      Remittances: results[1],
      Payed: results[2]
    };
  });

Note that $q.resolve() is only available since angular 1.4. If you use a prior version, use $q.when({}) instead of $q.resolve().

Upvotes: 3

pablochan
pablochan

Reputation: 5715

You're not using $q.all correctly. It takes an array (or object) of promises, not an array of deferreds.

Change

$q.all([PBdeferred, Rdeferred, Pdeferred])

to

$q.all([PBdeferred.promise, Rdeferred.promise, Pdeferred.promise])

Upvotes: 4

Related Questions