$scope.apply is firing “catch” as well as “then”

In Angular 1.6.2 and UI router, I am looking to only show the content of a page once it has been established on the server that the user has the correct role/permissions to access the page.

Without $scope.apply() catch() doesnt get fired but for some reason this isnt the case when I have it in there. Without $scope.apply() the vm.showContent variable doesnt seem to update the view as it should.

I am getting no Angular or JS errors so I said I would omit any other relevant code as I assume nothing else is causing an issue.

View/HTML

<div ng-show="data.showContent">
 // my html, not to be shown until vm.showContent is true     
</div>

Controller

// more JS
var vm = this;
vm.showContent = false;
// more JS
vm.hasRole = function (role, toState, event) {

    Auth.hasRole(role).then(function (data) {
        vm.showContent = true;
        // without this nothing is happening with the view
        $scope.apply();
        alert('has role'); // firing successfully
    }).catch(function () {
        alert('does not have role') // firing also if I add $scope.apply();
        if (event != false) {
            event.preventDefault();
            $state.go('no-permission');
        }
    });
}

Answer

Look at the error response value:

//}).catch(function () {
//LOG error response
}).catch(function(errorResponse) {
    console.warn(errorResponse);
    alert('does not have role') // firing also if I add $scope.apply();
    if (event != false) {
        event.preventDefault();
        $state.go('no-permission');
    }
});

The $scope.apply() is likely throwing:

Error: $rootScope:inprog Action Already In Progress

When an error is thrown in a success handler in a promise chain, the $q service skips to the first subsequent rejection handler in the chain.

For more information on the error, see AngularJS Error Reference – $rootScope/inprog


AngularJS 1.6 treats thrown errors same as regular rejections

With previously versions, thrown errors in success and rejection handlers would create console error messages. AngularJS 1.6 was changed to treat thrown errors the same as regular rejections:

$q:

Due to e13eea, an error thrown from a promise’s onFulfilled or onRejection handlers is treated exactly the same as a regular rejection. Previously, it would also be passed to the $exceptionHandler() (in addition to rejecting the promise with the error as reason).

–AngularJS Developer Guide – Migrating from v1.5 to v1.6 – $q

Leave a Reply

Your email address will not be published. Required fields are marked *