Reputation: 3428
I would like to check if user is logged each time the state I transition to or it's parent has some isLogged data attribute. My code is:
service.watchHasAccess = function(){
$rootScope.$on('$stateChangeStart', function(event,toState,toStateParams){
if(typeof toState.data !=='undefined' && typeof toState.data.loggedIn !== 'undefined' && toState.data.loggedIn == true){
api.getWithPromise('user/isLoggedIn').then(function(response){
if(response.status !=='OK'){
event.preventDefault();
FlashMessage.showError('Zaloguj się aby przejść tutaj.');
$state.go('MainPage');
}
});
}
});
The problem is that when transitioning to restricted state it does load, but it almost immediately redirects to MainPage state. It is like flash. It is because I use async request so I assume that state just transition no matter what result of request, but then response comes and I am transitioned properly. What I would like to achieve is to wait until promise get resolved then check and eventually redirect user to 'MainPage'. Is that possible ?
Upvotes: 1
Views: 620
Reputation: 25726
You would need to use promises for your asyc and resolve or reject the promise based on what is returned. I would suggest that the URL switching would take place in the $stateChangeError
event listener, which would be fired by rejection of the promise. You can pass the location you want to go to in the reject([data])
to the listener.
http://fiddle.jshell.net/L9jxf/2/
Some promise that will reject after a timeout (simulates server call)
protected: ['$timeout', '$q', function ($timeout, $q) {
var deferred = $q.defer();
$timeout(function () {
deferred.reject({type:'redirect',location:'401'});
}, 1000);
return deferred.promise;
}]
This handles the rejection
app.run(function ($rootScope, $state) {
$rootScope.$on('$stateChangeError', function (e, to, toParams, from, fromParams, error) {
if (error.type === 'redirect') {
$state.transitionTo(error.location);
}
});
});
Upvotes: 1