$digest already in progress when calling $rootScope.$apply() in quick succession

11,811

The problem is that it's performing $digest on $rootScope twice in quick succession and it throws the error when there's an overlap. To get around this, you can simply wrap both calls to $location.path() in $timeout, as you have done the first time in your plnkr example. This will force it to wait for the $digest cycle to complete.

You may also remove the 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 than the code in the original post.

Reference:

wait for end of $digest cycle

Share:
11,811
user1491636
Author by

user1491636

Updated on June 11, 2022

Comments

  • user1491636
    user1491636 almost 2 years

    So I have an AngularJS service listening for some events. On the handling of these events I need to call different controllers and ultimately load a new view. In one event handler I am using $location.path() then calling $rootScope.apply() to trigger the routing to the controller. This works fine for that event, but in others I get the following error: $rootScope:inprog Action Already In Progress. I'm guessing that it works in the first scenario because $rootScope.apply() is called from another callback function inside the listener function, where as the other handlers try to call it just 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 get it to work for all event handlers?

    plnkr example

  • user1491636
    user1491636 almost 10 years
    I tried that with no luck. The routing is not triggered at any point.
  • aw04
    aw04 almost 10 years
    Can you create an example jsfiddle or plunkr?
  • user1491636
    user1491636 almost 10 years
    Sure. Before I do that let me also mention that MY_EVENT is always triggered prior to MY_OTHER_EVENT. The time between the two events is an indeterminate.
  • aw04
    aw04 almost 10 years
    Ok. I think if you can create an example that replicates this it will help myself/others identify the problem.