$ digest is already running when $ rootScope is called. $ apply () in quick succession

So, I have an AngularJS service that listens for some events. When handling these events, I need to call different controllers and eventually load a new view. In one event handler, I use $ location.path () and then call $ rootScope.apply () to start routing to the controller. This works fine for this event, but in other cases I get the following error: $rootScope:inprog Action Already In Progress . I assume that it works in the first scenario, because $ rootScope.apply () is called from another callback function inside the listener function, where when other handlers try to call it only from the event listener function.

 //angular service $rootScope.$on('MY_EVENT', function (event, msg) { MyClass.doSomething(msg, function (response) { $location.path("/view1"); $rootScope.$apply(); //WORKS FINE }); }); $rootScope.$on('MY_OTHER_EVENT', function (event, msg) { $location.path("/view2"); $rootScope.$apply(); //ERROR }); 

How can I make it work for all event handlers?

Plnkr example

+6
source share
1 answer

The problem is that it executes $digest on $rootScope twice in quick succession and throws an error when overlapping. To get around this, you can simply wrap both calls to $location.path() in $timeout , as was the first time in your plnkr example. This will make him wait for the completion of the $digest cycle.

You can also remove explicit calls to $rootScope.$apply() .

 $rootScope.$on('FIRST_EVENT', function(event, msg) { $timeout(function() { $location.path("/view1"); }); }); $rootScope.$on('SECOND_EVENT', function(event, msg) { $timeout(function() { $location.path("/view2"); }); }); 

Note:

This code is based on the plnkr example, which is slightly different from the code in the original message.

Reference:

wait for the end of the cycle $ digest

+11
source

Source: https://habr.com/ru/post/973389/


All Articles