Find `$apply` or `$digest` invoker

72 views Asked by At

I'm looking for at way to track down the pesky error of

apply/digest is already in progress

I'm familier with not using the anti-pattern and have check my codebase for nested apply's/digest's.

The problem lies in third-party plugins in this case FormEditor and Flatpickr. I have nested FlatPickr (with angular add-on) into a formEditor cshtml file which gives me the pesky error.

Is there a way to track the location of all the invokation of apply and/or digest that are present in my project?

Or does anyone have a solution to formEditor with flatPickr and flatpickr angular add-on?

FormEditor: https://github.com/kjac/FormEditor FlatPickr: https://github.com/chmln/flatpickr FlatPickr add-on: https://www.npmjs.com/package/angular-flatpickr

SOLUTION: The problem was a $apply called by an eventListener which injected the apply into the running apply/digest. Used $timeout as suggested in the answer marked as correct. The location was found by looking into the error log as suggested in comments

1

There are 1 answers

1
Aviad On BEST ANSWER

AngularJS automatically triggers a $digest cycle in many cases (after ng-click triggered for example) so the solution is not to find all the "apply / digest" in your code because it won't help you to prevent this error.

The right approach is to control 3rd parties calls to $apply method.

One approach can be wrapping $apply call with a safety check:

if(!$scope.$$phase) {
  // place 3rd party updates to scope here
  $scope.$apply();
}

The problem with this method is that sometimes you code won't be called.

The better approach will be to wrap it with $timeout 0:

$timeout(function(){
  // place 3rd party updates to scope here 
});

This way you merged more naturally into angular digest cycle.