Question
I'm finding that I need to update my page to my scope manually more and more since building an application in angular.
The only way I know of to do this is to call $apply()
from the scope of my
controllers and directives. The problem with this is that it keeps throwing an
error to the console that reads :
Error: $digest already in progress
Does anyone know how to avoid this error or achieve the same thing but in a different way?
Answer
Don't use this pattern - This will end up causing more errors than it solves. Even though you think it fixed something, it didn't.
You can check if a $digest
is already in progress by checking
$scope.$$phase
.
if(!$scope.$$phase) {
//$digest or $apply
}
$scope.$$phase
will return "$digest"
or "$apply"
if a $digest
or
$apply
is in progress. I believe the difference between these states is that
$digest
will process the watches of the current scope and its children, and
$apply
will process the watchers of all scopes.
To @dnc253's point, if you find yourself calling $digest
or $apply
frequently, you may be doing it wrong. I generally find I need to digest when
I need to update the scope's state as a result of a DOM event firing outside
the reach of Angular. For example, when a twitter bootstrap modal becomes
hidden. Sometimes the DOM event fires when a $digest
is in progress,
sometimes not. That's why I use this check.
I would love to know a better way if anyone knows one.
From comments: by @anddoutoi
[angular.js Anti Patterns](https://github.com/angular/angular.js/wiki/Dev- Guide%3A-Anti-Patterns)
- Don't do
if (!$scope.$$phase) $scope.$apply()
, it means your$scope.$apply()
isn't high enough in the call stack.