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
- workaround for https://github.com/angular-ui/ui-router/issues/1022 — committed to nihgwu/hexo-hey by nihgwu 9 years ago
It seems like we have faced to the same issue.
$urlRouterProvider.otherwise
forces to redirect to a complex/root/child/child
state, which hasresolve
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 noresolve
is used. Resolved object is just a promise one, returned by $http or $resource.$promise; wrapping it with $q does not solve the problemUPD. 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()
usagewhich 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:
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:prevents infinite looping.
Maybe re-open the issue?
Also fixed by using @dmytro-shchurov and @KevinOl solution:
Can anyone explain the cause behind it? Can we expect it to be fixed in a future release?
Cheers!