ui-router: Redirect loop on state with errored resolve

In our code we are using the code in the faq for optional trailing slashes. We also have a number of states loading data using the resolve attribute.

I observe the following four cases when navigating to states that use resolve, both from other states, and when navigated to directly by URL:

Navigate from Data successfully resolved Data resolution failed
Another state Ends at expected state and url Stays on (or is returned to) original state and url
Another website Ends at expected state and url URL remains that of the failed state, but the actual state is ‘’ or the abstract root state

If we then include the redirection for trailing slashes in the FAQ, and navigate to the same states but without a trailing / then all of these cases other than the bottom right remain the same.

When navigating directly to a state whose resolution fails, we get into a loop where the redirect adds a /, starting a transition to the state, the state then fails during its resolve and redirects back to the address without a /. This loop continues flipping the / back and forth until we receive the following two ‘infinite digest’ errors.

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: $locationWatch; newVal: 7; oldVal: 6"],["fn: $locationWatch; newVal: 8; oldVal: 7"],["fn: $locationWatch; newVal: 9; oldVal: 8"],["fn: $locationWatch; newVal: 10; oldVal: 9"],["fn: $locationWatch; newVal: 11; oldVal: 10"]]
http://errors.angularjs.org/1.2.15/$rootScope/infdig?p0=10&p1=%5B%5B%22fn%3…2fn%3A%20%24locationWatch%3B%20newVal%3A%2011%3B%20oldVal%3A%2010%22%5D%5D
    at http://code.angularjs.org/1.2.15/angular.js:78:12
    at Scope.$digest (http://code.angularjs.org/1.2.15/angular.js:12070:19)
    at Scope.$apply (http://code.angularjs.org/1.2.15/angular.js:12279:24)
    at http://code.angularjs.org/1.2.15/angular.js:1382:15
    at Object.invoke (http://code.angularjs.org/1.2.15/angular.js:3805:17)
    at doBootstrap (http://code.angularjs.org/1.2.15/angular.js:1380:14)
    at bootstrap (http://code.angularjs.org/1.2.15/angular.js:1394:12)
    at angularInit (http://code.angularjs.org/1.2.15/angular.js:1307:5)
    at http://code.angularjs.org/1.2.15/angular.js:21163:5
    at HTMLDocument.trigger (http://code.angularjs.org/1.2.15/angular.js:2445:7) angular.js:9563
Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: $locationWatch; newVal: 7; oldVal: 6"],["fn: $locationWatch; newVal: 8; oldVal: 7"],["fn: $locationWatch; newVal: 9; oldV...<omitted>...5D 

I am unsure of what the expected behavior here is, though I would assume a digest error is not it. I would probably expect the same behavior as I would see without the / redirect - stay on the original URL, or even the errored state’s URL but not complete the transition.

Is there something I should do differently here to avoid this case, or is this a bug?

Plunker example here: http://plnkr.co/edit/28AQYE?p=preview

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 27 (1 by maintainers)

Commits related to this issue

Most upvoted comments

It seems like we have faced to the same issue. $urlRouterProvider.otherwise forces to redirect to a complex /root/child/child state, which has resolve specified. Everything is fine in two cases: 1) When user url does not end with slash (like localhost/#) or 2) When exact state is specified in the url (like localhost/#/root/child/child). In case url is typed as localhost/#/ we’ve got ‘10 $digest iterations reached’ Of course everything is fine in all cases when no resolve is used. Resolved object is just a promise one, returned by $http or $resource.$promise; wrapping it with $q does not solve the problem

UPD. As a result of investigation, the reason of such error was caused by a bug in code of resolving routine, which was raised only after a service was compiled run-time, and for some reason was not reported to a browser console. But everything else remains the same: ‘/#’ and ‘#/state/’ works (this means no infinite loop), ‘/#/’ does not work. PS I’ve found an example of more correct .otherwise() usage

$urlRouterProvider.otherwise(function ($injector) {
            var $state = $injector.get('$state');
            $state.go('your.state');
        });

which did not cause infinite loop. It’s useful. But the compilation error is still not reported and it’s sad. Test your resolvers before you use them with $state.

I can confirm that this bug still happens. I solved it with this:

$urlRouterProvider.otherwise(function($injector) {
  var $state = $injector.get('$state');
  return $state.go('some.state');
});

I am using Angular 1.6.4 and ui-router 0.4.2

I also just experienced this with ionic. $urlRouterProvider.otherwise(function($injector)… Fixed the issue. Just spent 3 hours trying to figure out why the infinite loop.

@eddiemonge This is still happening on 0.2.18 using Angular 1.5.2.

Above solution fixed it for me. Replacing .otherwise('some.state') with:

$urlRouterProvider.otherwise(function($injector) {
  var $state = $injector.get('$state');
  return $state.go('some.state');
});

prevents infinite looping.

Maybe re-open the issue?

Also fixed by using @dmytro-shchurov and @KevinOl solution:

$urlRouterProvider.otherwise(function($injector) {
  var $state = $injector.get('$state');
  $state.go('home');
});

Can anyone explain the cause behind it? Can we expect it to be fixed in a future release?

Cheers!