iJade
iJade

Reputation: 23811

Error: $digest already in progress

I'm getting this error while trying to call

        function MyCtrl1($scope, $location, $rootScope) {
      $scope.$on('$locationChangeStart', function (event, next, current) {
        event.preventDefault();
        var answer = confirm("Are you sure you want to leave this page?");
        if (answer) {
          $location.url($location.url(next).hash());
          $rootScope.$apply();
        }
      });
    }

MyCtrl1.$inject = ['$scope', '$location', '$rootScope'];

Error is

Error: $digest already in progress

Upvotes: 32

Views: 72278

Answers (5)

user2217057
user2217057

Reputation: 237

josliber's answer solved a similar $digest problem that I was having. I just used

$scope.$evalAsync(function(){ 
   // code here
});

Good article here https://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm

Upvotes: 2

Hanmant Rachmale
Hanmant Rachmale

Reputation: 45

Use

$scope.evalAsync(function(){ 
});

instead of

$scope.$apply(function(){
});

Upvotes: 2

Hazarapet Tunanyan
Hazarapet Tunanyan

Reputation: 2865

Because your $scope.$apply() is inside AngularJs environment.In general I will not suggest you to use $apply(), moreover of $rootScope.$apply() functions make your application run slowly.It runs a new cycle of your whole scope.

Upvotes: 0

bmleite
bmleite

Reputation: 26880

Duplicated: Prevent error $digest already in progress when calling $scope.$apply()

That error you are getting means Angular's dirty checking is already in progress.

Most recent best practices say that we should use $timeout if we want to execute any code in the next digest iteration:

$timeout(function() {
  // the code you want to run in the next digest
});

Previous response: (don't use this approach)

Use a safe apply, like this:

$rootScope.$$phase || $rootScope.$apply();

Why don't you invert the condition?

$scope.$on('$locationChangeStart', function (event, next, current) {                
    if (confirm("Are you sure you want to leave this page?")) {
        event.preventDefault();
    }
});

Upvotes: 62

aw04
aw04

Reputation: 11187

For others looking to troubleshoot this error, it's worth noting that the docs seem to suggest using the $timeout service to ensure the code will be called in a single $apply block.

$timeout(function() {
  $scope.someData = someData;
});

Also discussed in this question if you look past the accepted answer.

Upvotes: 13

Related Questions