user1829319
user1829319

Reputation: 743

$q.all works for the first call only

Not sure why the q.all is not working the 2nd time e.g. the second time it does not wait for all the promises to be resolved.

Please have a look at the example and press the "call services" button. First time it waits until both promises are resolved but if you press the button again it immediately responds, not sure why?

http://plnkr.co/edit/JNJmX1fjsmxrxYuiNHJb?p=preview

 var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, $q, MyService1, MyService2) {
  $scope.name = 'World';

  $scope.Status1 = 'Waiting';
  $scope.Status2 = 'Waiting';
  $scope.buttonValue = "Call Services";

  $scope.doServices = function() {

    $scope.Status1 = 'Waiting';
    $scope.Status2 = 'Waiting';
    $scope.buttonValue = "Working ...";
    console.log($scope.Status1)

    var promise1 = MyService1.doIt();
    var promise2 = MyService2.doIt();

   $q.all([promise1, promise2]).then(
      function() {
        $scope.Status1 = 'Done';
      },
      function() {
        $scope.Status1 = 'Failed';
      }
    ).finally(function() {
      $scope.Status2 = 'Done waiting';
      $scope.buttonValue = "Call Services";
      //promises = null;
    });

  }

  $scope.callServices = function() {
     $scope.Status1 = 'Waiting';
  $scope.Status2 = 'Waiting';
    $scope.doServices();
  }

  $scope.reset = function() {
    $scope.Status1 = 'Waiting';
    $scope.Status2 = 'Waiting';
  }

});

app.service("MyService1", function($q, $timeout) {

  var deferred = $q.defer();

  this.doIt = function() {
    $timeout(function() {
      console.log("Service 1 called!");
      deferred.resolve("Service 1 done!");
    }, 2000);

    return deferred.promise;
  }
});


app.service("MyService2", function($q, $timeout) {

  var deferred = $q.defer();

  this.doIt = function() {
    $timeout(function() {
      console.log("Service 2 called!");
      deferred.resolve("Service 2 done!");
    }, 5000)

    return deferred.promise;
  }
});

Upvotes: 3

Views: 326

Answers (1)

JB Nizet
JB Nizet

Reputation: 692043

A promise can only be resolved once. Your service always returns the same promise. Once it's resolved, it's resolved.

You're using an anti-pattern, BTW. $timeout already returns a promise. All you should have in your service is

app.service("MyService1", function($timeout) {

  this.doIt = function() {
    return $timeout(function() {
      console.log("Service 1 called!");
      return "Service 1 done!";
    }, 2000);
  }
});

Same for service 2, BTW. But since both services to exactly the same thing (except for the duration of the timeout), and don't do anything that $timeout doesn't already do, you could just use $timeout directly from your controller.

Upvotes: 3

Related Questions