Reputation: 5940
I'm using angular-ui's UI-Router in my project and on state change I want to check if the user has access to the page. If not I popup a login modal.
$rootScope.$on('$stateChangeStart', function(evt, toState) {
if (!authentication.authorize(toState.data.access)) {
evt.preventDefault();
$state.go('login', {}, {notify: false});
}
});
The login state, using a modal from UI-Bootstrap:
angular.module('components.security').config(function($stateProvider) {
$stateProvider.state('login', {
onEnter: function($state, $modal) {
$modal.open({
templateUrl: "/components/security/login.html",
controller: 'LoginCtrl as controller'
});
}
});
});
It's working perfectly fine on the first page load: The ui-view isn't rendered, the login modal pops up, and when the user logs in I call $urlRouter.sync();
and the view is loaded.
However, if you navigate from page to page this is what should happen:
Instead what happens is this:
So what I'd really like is that the url actually changes to /pageB but the ui-view doesn't load until you call sync.
Upvotes: 3
Views: 1350
Reputation: 8216
Have you considered saving toState and angular.copy(toParams) in your authentication $stateChangeStart listener, then triggering $state.go after the user has logged in?
The URL is not set to /pageB when the user transitions there because when you preventDefault, the transition is prevented (and the url is reset to pageA):
if ($rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams).defaultPrevented) {
syncUrl();
return TransitionPrevented;
}
Upvotes: 2