AngularJS delayed view update when a promise is resolved

Viewed 100

I have some action inside a controller. It contains a promise object which, when resolved, should update a view via the controller as binding. The issue is that the resolved value is correct (logged in a console), but assigning it to a controller doesn't update the view. It only updates when the action containing that promise is executed again. So, if I keep on executing it by pressing a button, the update is delayed by one execution.

I'm using AngularJS 1.6.5. I'm not using $q. There is no $scope either, so no $apply, please.

My simplified controller with 2 members to compare the behaviour with and without a promise:

var vm = this;

vm.textSync = 0;
vm.textAsync = 0;

vm.onclick = function()
{
    var action = new Promise(function(resolve, reject)
    {
        resolve(vm.textAsync + 1);
    });

    action.then(function(result)
    {
        console.log(result);
        vm.textAsync = result;
    });

    vm.textSync++;
};

The logged value is equal to the incremented textSync (1,2,3,...), but textAsync in a view is equal to textSync - 1 after each click (so it's 0,1,2,...). Why is that and how to fix it?

My simplified view:

<input type="button" value="Click me" ng-click="$ctrl.onclick()" />
<input ng-model="$ctrl.textSync" />
<input ng-model="$ctrl.textAsync" />
1 Answers

Since you don't want to trigger digest cycle you could use $timeout with 0 sec to wait for digest cycle so wrap your promise like this, just omit 0 after function - not necessary:

$timeout(action.then(function(result) {
        console.log(result);
        vm.textAsync = result;
    }));
Related