22

Folks,

I have my code setup somewhat as below:

$scope.init = function(){
  return $q.all([resource1.query(),resource2.query(),resource3.query()])
            .then(result){
               $scope.data1 = result[1];
               $scope.data2 = result1[2];
               $scope.data3 = result[3];


               console.log(data1); //prints as [$resolved: false, $then: function]

               doSomething($scope.data1,$scope.data2); 
                 }
}

I was under the impression that the "then" function will be called only when all the resources get resolved. However this is not what I am seeing in my code. If I print data1, I get unresolveed.

Any clue as to what I am missing here ??

runtimeZero
  • 26,466
  • 27
  • 73
  • 126
  • Does `resource1.query()`, etc. return a Promise? [`all`](http://docs.angularjs.org/api/ng.$q#all) expects an Array of Promises, and if they aren't Promises they will be considered immediately completed. – Ross Allen Sep 05 '13 at 22:31
  • I am using angular 1.15 and it returns something like this [$resolved: false, $then: function] I believe this is a promise – runtimeZero Sep 06 '13 at 13:59
  • Please note that the indices in the result array are zero-based as would be expected of an array, so $scope.data1 = result[0], etc. –  Mar 23 '15 at 16:08

4 Answers4

56

I ran into this problem, and it was quite confusing. The problem appears to be that calling a resource action doesn't actually return an http promise, but an empty reference (that is populated when the data returns from the server -see the return value section of the $resource docs).

I'm not sure why this results in .then(result) returning an array of unresolved promises, but to get each resource's promise, you need to use resource1.query().$promise. To re-write your example:

$scope.init = function() {
  return $q.all([resource1.query().$promise, resource2.query().$promise, resource3.query().$promise])
           .then( function(result) {
             $scope.data1 = result[0];
             $scope.data2 = result[1];
             $scope.data3 = result[2];

             console.log($scope.data1);

             doSomething($scope.data1,$scope.data2); 
           })
}

I hope that saves someone else some time.

T.W.R. Cole
  • 4,106
  • 1
  • 19
  • 26
cdidyk
  • 676
  • 6
  • 5
  • 3
    This is really confusing and best I can tell not documented anywhere. Without the ```$promise``` after the resource call I was getting an unfulfilled promise in .then which makes no sense. Thanks for this. – blu Dec 18 '13 at 16:20
  • This should be marked as the answer to this question. – Nicholas Cloud Apr 10 '14 at 20:15
  • result array begins with zero, so $scope.data1 = result[0] and so on is what you would want there. –  Mar 23 '15 at 16:10
  • Thank you! This was driving me nuts today. – PCalouche Oct 11 '16 at 14:46
0

you are printing data1 not $scope.data1

console.log(data1);

if i were you i would use it as follows

$scope.init = function(){
return $q.all([resource1.query(),resource2.query(),resource3.query()])
        .then(result){
          console.log(result[1]);
           $scope.data1 = result[1];
           $scope.data2 = result1[2];
           $scope.data3 = result[3];

           doSomething($scope.data1,$scope.data2); 
             }
}
dursun
  • 1,861
  • 2
  • 21
  • 38
0

Like @cdidyks answer this utilises $promise, but in my opinion it is a better design pattern as it doesn't rely on all resources to be completed for assignment, and makes the $promises more accessible in less code.

$scope.data1 = resource1.query();
$scope.data2 = resource2.query();
$scope.data3 = resource3.query();

$scope.init = function() {
  return $q.all([
      $scope.data1.$promise,
      $scope.data2.$promise,
      $scope.data3.$promise
    ])
    .then(function(result) {
        console.log('all done');
      doSomething($scope.data1, $scope.data2);
    })
}
Blowsie
  • 40,239
  • 15
  • 88
  • 108
0

For those still trying to figure out a better way to go about this, try this:

  resource.query().$promise.then(function(result) {
    console.log(result);
    // Do something else, like instantiate a JS driven table
  });
Tim Selaty Jr.
  • 599
  • 4
  • 6