Search code examples
angularjsangularjs-scopeangularjs-lifecycle

Error: $rootScope:inprog -- What is the correct way to 'not' execute $apply in angular?


AngularJS Wiki - Anti-Patterns states the following:

Don't do if (!$scope.$$phase) $scope.$apply(), it means your $scope.$apply() isn't high enough in the call stack.

And I kind of understand this. There is a built in logic that determines when what needs to be executed. And when an external developer, without direct insigt in the runtime executions of different procedures, determines what should run where, it counteracts the framework.

But I am currently uploading a large file where the upload progress is displayed through a progress bar. The library I use (resumableJS) in turn has an event called fileProgress, that is called when the upload is progressing. If I do nothing during that event, the bar is not updating. If I put $scope.$apply() there, the bar is updated accordingly, but I get the digest and/or apply already in progress error. Finally, with the help of the $$phase check I get the best of both worlds, an updated progress bar without any errors.

So what is the correct alternative to get my bar updated while not interfering with the angulars processing order?


Solution

  • In your case you are trying to run a digest cycle, when a digest cycle is already in phase. So it's throwing an error

    You can use something like setTimeout(fn,0). What it basically does is it adds new message to the queue immediately, and will be processed when the currently executing code is finished.

    So in your angular code, where you are explicitly doing your $scope.$apply(), change it to the code below and it should work.

    $timeout(function(){
       $scope.$apply();
    },0)