I have an AngularJS app that uses UI-Router and has Authentication & Authorisation.
When changing $state I check authentication and authorisation and on failure I intend to redirect or request login.
$rootScope.$on('$stateChangeStart', function (event, toState) {
var requiresAuth = toState.data.requiresAuth;
if (requiresAuth) {
var authorizedRoles = toState.data.authorizedRoles;
if (!AuthService.isAuthorized(authorizedRoles)) {
event.preventDefault();
if (AuthService.isAuthenticated()) {
// user is not allowed
notifyError({ status: "Denied", statusText: "You don't have permission" });
} else {
// user is not logged in
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
$rootScope.$state.go('app.dashboard');
}
}
});
My problem is that when on state 'app.dashboard' and attempting to navigate to a state on which I don't have permission or am not authenticated I see the state change (breadcrumbs change on view) but then the $stateChangeStart code above kicks in and should send the state back to 'app.dashboard' and it does... I can debug and see the state is indeed changed back to app.dashboard but because the state already was 'app.dashboard' a reload doesn't take place therefore my navigation ui-sref-active directives don't update and the view (breadcrumbs) doesn't update.
<li data-ui-sref-active="active">
<a data-ui-sref=" app.dashboard" title="Dashboard">
<i class="fa fa-lg fa-fw fa-home"></i> <span class="menu-item-parent"> Dashboard</span>
</a>
</li>
This all makes sense because AngularS is designed to prevent page reloads however I'm not sure how best to code around the problem. I've taken advice and code from this answer and it works but I'm a little concerned about issues this could introduce as I further develop the application.
.config(function($provide) {
$provide.decorator('$state', function($delegate)
{
$delegate.go = function(to, params, options)
{
return $delegate.transitionTo(to, params, angular.extend(
{
reload: true,
inherit: true,
relative: $delegate.$current
}, options));
};
return $delegate;
});
Ideally, I'd prefer to achieve what I want without changing the behaviour of UI-Router's $state provider. Has anyone got any ideas?