I'm looking into chaining promises to populate my scope, and then having the scope automatically update the dom.
I'm running into problems with this though.. If I call "then" on an already resolved promise, it creates a new promise (that will call the success function asynchronously but almost immediately). I think the problem is that we've already left the digest cycle by the time the success function is called, so the dom never updates.
Here is the code:
<div ng-controller="MyCtrl">
Hello, {{name}}! <br/>
{{name2}}<br/>
<button ng-click="go()">Clickme</button><br/>
{{name3}}
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $q) {
var data = $q.defer();
setTimeout(function() {$scope.$apply(data.resolve("Some Data"))}, 2000);
var p = data.promise;
$scope.name = p.then(angular.uppercase);
$scope.name2 = p.then(function(x) { return "Hi "+x;});
$scope.go = function() {
$scope.name3 = p.then(function(x) {
// uncomment this to make it work:
//$scope.$apply();
return "Finally: "+x;
});
};
}
http://jsfiddle.net/QZM4d/
Is there some way to make this work without calling $apply every time I chain promises?
To quote @pkozlowski.opensource:
In AngularJS the results of promise resolution are propagated asynchronously, inside a $digest cycle. So, callbacks registered with then() will only be called upon entering a $digest cycle.
So, when the button is clicked, we are in a digest cycle. then() creates a new promise, but the results of that then() will not be propagated until the next digest cycle, which never comes (because there is no $timeout, or $http, or DOM event to trigger one). If you add another button with ng-click that does nothing, then click that, it will cause a digest cycle and you'll see the results:
<button ng-click="">Force digest by clicking me</button><br/>
Here's a fiddle that does that.
The fiddle also uses $timeout instead of setTimeout -- then $apply() isn't needed.
Hopefully it is clear when you need to use $apply. Sometimes you do need to call it manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With