Reputation: 1855
I am using Angular 1.5.8
and angular-ui-router 0.3.2
.
I need to resolve an authentication method on every route change.
I dont want to add the resolve property for each route so I created this in App.run
//check permissions
$rootScope.$on('$stateChangeStart', function (evt, toState) {
if ($localStorage.token || toState.authenticated) {
$http.defaults.headers.common = {
'Authorization': 'Token ' + $localStorage.token,
'Accept': 'application/json'
};
permissionAPI.me()
.then(function(data){
$rootScope.user = data;
})
.catch(function(){
if(toState.authenticated) {
$rootScope.logout();
}
})
}
else {
if(toState.authenticated) {
$rootScope.logout();
}
}
});
`
It is usually working well, But I noticed that many times the application is routing before the promise permissionAPI.me()
resolved and that causing errors later.
How can I make sure the route will take effect just after that promise?
Or, how can I make a main resolve
for all of my routes by passing that promise from $stateChangeStart
?
Thank you!
Upvotes: 3
Views: 1633
Reputation: 221
Create an app state! Abstract states are useful for if you need to access data consistently across your application, but don't want to have that data associated with a specific view.
$stateProvider
.state('app', {
url: '/app/',
template: '<div ui-view></div>',
controller: 'AppCtrl',
abstract: true,
resolve: {
ActiveUser: function (AuthService) {
return AuthService.whoAmI();
}
}
})
.state('app.home', {
url: '',
templateUrl: 'app.home.html',
controller: 'HomeCtrl',
resolve: {
Categories: function (ActiveUser, MessagesService) {
return MessagesService.getAll(User);
}
}
});
You can then access that data in subsequent resolve blocks or in your controllers like app.controller('ExampleCtrl', function (ActiveUser) {});
as long as your controller is in a child state of 'app'
. This is achieved with the naming convention 'app.'
Upvotes: 2