-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed
Description
Here is a minimal example I made to reproduce my issue:
angular.module('routerTestApp', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/state/a');
$stateProvider.
state('state', {
url: '/state',
abstract: true,
resolve: {
parentResolved: ['$timeout', function ($timeout) {
return $timeout(function () {
return [];
}, 1000);
}]
}
}).
state('state.a', {
url: '/a',
resolve: {
resolved: ['$q', 'parentResolved', function ($q, parentResolved) {
return $q.reject({ redirect: 'state.b' });
}]
}
}).
state('state.b', {
url: '/b'
});
}])
.run(['$rootScope', '$exceptionHandler', '$state', function ($rootScope, $exceptionHandler, $state) {
$rootScope.$on('$stateChangeError', function (e, toState, toParams, fromState, fromParams, error) {
if (error && error.redirect) {
return $state.go(error.redirect);
}
$exceptionHandler(error);
});
}]);
The problem is when going to any non-existent url such as '/abc' for example - app falls to infinite 'location change' loop. Url should be pasted directly to browser address string because if previously we entered some valid state all subsequent redirects would work as expected.
By 'location change' loop I mean following:
- $urlRouterProvider.otherwise('/state/a') send us to 'state.a'
- 'state.a' resolve failed so $stateChangeError handler is called
- handler redirects us to 'state.b'
- but syncUrl() function that called in ui-router after firing $stateChangeError sees that currentLocation (it's '/abc' at that moment) doesn't match $location.url() and sends us back to '/abc' - so we are returning to point 1).
Metadata
Metadata
Assignees
Labels
No labels