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