Roy Truelove
Roy Truelove

Reputation: 22466

Angularjs - watching a promise - getting undefined

I know that the templates can bind to either a promise or a real value, and when that value changes the template is updated.

I want to do something similar in a directive, where I watch for changes to a promise and reload the data in the directive when that promise is updated.

However, when I watch a promise, it seems to register the change but then is immediately set to 'undefined'.

See http://plnkr.co/edit/eOjkuvyrQvKhkAbVLGVG?p=preview

As you can see the template is updated with no problem, but if you check the console, the 'isNotAPromise' watch works as expected, but the 'isAPromise' watch is triggered twice, both with 'undefined'.

Any clues?

Here's the code to make SO happy:

app.controller('MainCtrl', function($scope, $q) {
  var c;
  c = 1;
  setInterval(function() {
    c = c + 1;
    console.log('---------------');
    console.log(['c changed to ', c]);
    return $scope.$apply(function() {
      $scope.isNotAPromise = c;
      return $scope.isAPromise = $q.when(c);
    });
  }, 1000);
  $scope.$watch('isAPromise', function(newVal, oldVal) {
    return console.log(['isAPromise changed', oldVal, newVal]);
  });
  return $scope.$watch('isNotAPromise', function(newVal, oldVal) {
    return console.log(['isNotAPromise changed', oldVal, newVal]);
  });
});

Thanks, Roy

Upvotes: 1

Views: 2367

Answers (1)

Mark Rajcok
Mark Rajcok

Reputation: 364707

I added a timestamp to determine when the two watches were triggering:

console.log [+new Date(), 'isAPromise changed', oldVal, newVal]

Sample output:

["c changed to ", 3] app.js:12
[1366223960472, "isAPromise changed", 2, undefined] app.js:19
["isNotAPromise changed", 2, 3] app.js:22
[1366223960473, "isAPromise changed", undefined, 3] 

So, the two watches on isAPromise are firing 1 millisecond apart. I'll guess that what happens is that when $q.when(c) is first assigned to $scope.isAPromise, it is undefined because the promise isn't resolved yet. Then the promise is resolved (probably during the very next $digest loop) and isAPromise is then set to the value of the (resolved?) promise.

Upvotes: 2

Related Questions