Reputation: 4306
Sometimes i need to use $scope.$apply
, for example when i use jQuery ajax or some non-angular-js eventlisteners. In those cases i have an asynchronous callback and there i use $scope.$apply
so that changes to the scope are picked up by angular and watches are triggered. Please correct me if that is the wrong use of $scope.$apply
.
This seems to work and the view is updated. However in some rather rare cases I get a "digest already in progress" error. I don't see how this can be possible, since the callback is not synchronous. So I wonder if it is possible that my asynchronous callback with the $scope.$apply
in it can by chance collide with an ongoing digest? If so, how can I prevent this from happening?
edit:
One possibility to check for a digest is checking $$phase: if (!$scope.$$phase) $scope.$apply()
but this is an anti-pattern as the angularjs wiki says: https://github.com/angular/angular.js/wiki/Anti-Patterns
I want to fully understand why it is possible that I encounter a digest in an asynchronous callback. And why this is an antipattern.
Upvotes: 4
Views: 601
Reputation: 7196
You are calling $apply
on an existing scope, so it's definitely possible that you are calling apply while it is currently digesting. Some people might suggest checking $$phase but that has been discouraged as an anti-pattern
You have two options if you are running into this problem, even occasionally. One is to do as the anti-pattern implies and make sure your $scope.$apply
is as high as possible up the chain.
However, this won't help if you are asynchronously calling $apply
on the same $scope in rapid succession. The answer then is often to throttle the $apply
so that it only happens every few hundred milliseconds. This is a common practice when using something like socket.io
that can fire events which could cause you to re-apply many times.
Upvotes: 1
Reputation: 4306
I recently asked a similiar question on why if (!$scope.$$phase) $scope.$apply()
is an anti-pattern here: Why is using if(!$scope.$$phase) $scope.$apply() an anti-pattern?
The answer there also contains the answer to this question.
Upvotes: 1
Reputation: 2685
Async Callbacks are an appropriate time to use the $apply, there are edgecases I have run into as well where i get that error. They are usually because I am doing something wonky, I have found that a "Conditional Apply" works well for these.
if(!$scope.$$phase) {
//$digest or $apply
}
AngularJS : Prevent error $digest already in progress when calling $scope.$apply()
Upvotes: 0
Reputation: 7159
I think, that its normal, but it will be better to move code to services and resources with angular style. To prevent error you can check current state
scope.$$phase
To prevent calling $apply
Upvotes: 0