Kevin Renskers
Kevin Renskers

Reputation: 5940

UI-Router: Change url without loading state or defer loading the state?

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

Answers (1)

Chris T
Chris T

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

Related Questions