Angular UI router issue when redirecting to template after issue resolved ()
So I needed to understand this problem for a very long time and move on to mcve . Like this: I am trying to redirect the user to the login page when they are not authenticated (this is very simple). Here is the code:
HTML:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.min.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<div ui-view></div>
<script id="login.html" type="text/ng-template">
l
</script>
<script id="welcome.html" type="text/ng-template">
w
</script>
</body>
</html>
JS:
angular.module('starter', ['ui.router'])
.run(["$rootScope", "$state", function($rootScope, $state) {
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
if (error === "nope") {
$state.go("login");
}
});
}])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/welcome');
$stateProvider
.state('welcome', {
url: '/welcome',
templateUrl: 'welcome.html',
resolve: {
"auth": ["$q", function($q) {
return $q.reject("nope");
}]
}
})
.state('login', {
url: '/login',
templateUrl: 'views/login.html'
})
});
"views / login.html" only contains "vl" to see it on screen. So, when the above code is run, the output is good, but look at the Chrome console:
Now, the crazy part is if you change the JS and replace
templateUrl: 'views/login.html'
in login state just
templateUrl: 'login.html'
using the ng template defined in the html EVERYTHING IS GOOD! So I guess using a file as a template should trigger some kind of observer or something ... Well no, I'm just out of ideas.
Thank you for your help!
[EDIT]
here are two things that might help:
- Error when using ngRoute instead of UI router
- Error replacing Angular version with 1.2.25
So I think this is a bug with UI Router and Angular 1.3. But I donβt know at all what to do to solve this problem.
source to share
You need to call event.preventDefault()
before you call $state.go()
.
See it here: http://plnkr.co/edit/eUosIpdN7adJFxfDo3kV?p=preview
The main reason this error occurs, as you have already identified, is because the url pattern is 'views/login.html'
not exsit. You said that when changing the url pattern from 'views/login.html'
to 'login.html'
everything worked and it makes sense because this pattern exists.
The reason you see an infinite digest error is because every time you try to access the state welcome
, the transformer auth
generates an error that raises the event $stateChangeError
as you would expect it to. Everything is fine until the moment when he tries to go into a state login
. The attempt to go into the state login
failed because the url pattern 'views/login.html'
does not exist and this failure triggers a redirect redirect otherwise
to get you back into the state welcome
. You can see at this point that returning to the state welcome
will restart the entire loop and invoke an infinite digest loop.
Just make sure the template urls are correct so that this doesn't happen, as you've already discovered.
source to share
I had the same problem and this is how I solved it
.run(function($rootScope, $state) {
$rootScope.$on('$stateChangeError', function() {
// Redirect user to our login page
$state.go('auth.login');
});
});
Below I have enclosed my entire page so you can see how it all works 'use strict';
angular.module('mean.pdash').config(['$stateProvider',
function($stateProvider) {
// Check if the user is connected
var checkLoggedin = function($q, $timeout, $http, $location) {
// Initialize a new promise
var deferred = $q.defer();
$http.get('/loggedin').success(function(user) {
// Authenticated
console.log(user);
if (user !== '0') {
$timeout(deferred.resolve);
} else {
$timeout(deferred.reject);
}
});
return deferred.promise;
};
$stateProvider.state('pdash', {
url: '/',
templateUrl: 'pdash/views/index.html',
controller: 'PdashController',
resolve: {
checkLoggedin: checkLoggedin
}
});
}
])
.run(function($rootScope, $state) {
$rootScope.$on('$stateChangeError', function() {
// Redirect user to our login page
$state.go('auth.login');
});
});
source to share