Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: [$rootScope:inprog] $digest already in progress

I'm trying so send a form (using a directive) when a property in the model changes (so I watch the property), but when I trigger the submit event, I get the error: "Error: [$rootScope:inprog] $digest already in progress", how can I avoid this error, here is my code:

app.directive("autoSubmit", function(){
  return {
    link: function(scope, element, attrs){

      scope.$watch("valid", function(){ 
        if(scope.valid == 1) {
          console.log("send form");
          element.triggerHandler("submit");
        }
      });
    }
  }
});

Heres is he plunk: http://plnkr.co/edit/cosJLkhUEKv55G8uU1Ea (to reproduce the error, just change the value of the textbox to 1)

Thanks in advance for your help.

like image 569
PachinSV Avatar asked Aug 08 '14 05:08

PachinSV


People also ask

How do you resolve $Digest already in progress?

There are a few ways to deal with this. The easiest way to deal with this is to use the built in $timeout, and a second way is if you are using underscore or lodash (and you should be), call the following: $timeout(function(){ //any code in here will automatically have an apply run afterwards });

What is rootScope apply ()?

$scope.$apply() This function is used to execute an expression in Agular. The function expression is optional and you can directly use $apply(). This is used to run watcher for the entire scope. $rootScope.$digest()

What is $apply in AngularJS?

In AngularJS, $apply() function is used to evaluate expressions outside of the AngularJS context (browser DOM Events, XHR). Moreover, $apply has $digest under its hood, which is ultimately called whenever $apply() is called to update the data bindings.


1 Answers

The problem is that there is already a $digest cycle running (obviously watch one) when you try to trigger an event. So you should simply wait until its done and raise the event during the next one. You can $timeout service for that:

app.directive("autoSubmit", function($timeout) {
    return {
        link: function(scope, element, attrs) {
            scope.$watch("valid", function() {
                if (scope.valid == 1) {
                    console.log("send form");
                    $timeout(function() {
                        element.triggerHandler('submit');
                    })
                }
            });
        }
    }
});

Demo: http://plnkr.co/edit/bRXfi9kFVFICgFUFvtZz?p=preview

Another way around is to invoke ngSubmit function manually yourself using $parse service:

app.directive("autoSubmit", function($parse) {
    return {
        link: function(scope, element, attrs) {
            scope.$watch("valid", function() {
                if (scope.valid == 1) {
                    console.log("send form");
                    var submitHandler = $parse(attrs.ngSubmit)(scope);
                    if (submitHandler) {
                        submitHandler();
                    }
                }
            });
        }
    }
});

Demo: http://plnkr.co/edit/vNI8OwfnxSQJ6tQLpFqZ?p=preview

like image 67
dfsq Avatar answered Oct 03 '22 00:10

dfsq