Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angularjs + ui-router: redirect to login page when user is not logged in on each state change

I'm building a simple blog application with angularjs and ui-router and I want to listen for each state change and check if user is logged in. In case he isn't I want to redirect him to the login page.

The scenario is quite simple and I was trying to implement this solution with no luck.

This is the relevant code:

app.config(function($stateProvider, $urlRouterProvider){
    $stateProvider.state('app', {
        url: '',
        abstract: true
    });
    $urlRouterProvider.otherwise('blogs');
});

app.run(function($rootScope, $state, $location, UserService){
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
    console.log("state change: from state: " + fromState.name + " to state: " + toState.name);
        let loggedIn = UserService.isLoggedIn();
        if (toState.name !== 'app.login' && !loggedIn){
            event.preventDefault();
            $state.go('app.login');
    });
});

Where 'app.login' is defined as the login state and 'blogs' is the url of my main feed that I want the app will go to at startup.

When looking into chrome console, when no user is logged in, i see:

[HMR] Waiting for update signal from WDS...
state change: from state:  to state: app.blogs
state change: from state:  to state: app.login
state change: from state:  to state: app.blogs
state change: from state:  to state: app.login
state change: from state:  to state: app.blogs
state change: from state:  to state: app.login
state change: from state:  to state: app.blogs
state change: from state:  to state: app.login
state change: from state:  to state: app.blogs
state change: from state:  to state: app.login
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.4.5/$rootScope/infdig?p0=10&p1=%5B%5D
    at REGEX_STRING_REGEXP (angular.js:68)
    at Scope.$get.Scope.$digest (angular.js:15753)
    at Scope.$get.Scope.$apply (angular.js:15986)
    at bootstrapApply (angular.js:1658)
    at Object.invoke (angular.js:4473)
    at doBootstrap (angular.js:1656)
    at Object.bootstrap (angular.js:1676)
    at Object.<anonymous> (bootstrap.js:4)
    at __webpack_require__ (bootstrap 7b71f5eb02d2540fe63f:520)
    at fn (bootstrap 7b71f5eb02d2540fe63f:75)
Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.4.5/$rootScope/infdig?p0=10&p1=%5B%5D
XHR finished loading: GET "http://localhost:8080/login/login.html".

And it appears for several times. Also - the url is jumping between /login and /blogs.

What am I doing wrong?

(Edit: I added some debug to the console.log)

like image 454
Shikloshi Avatar asked Sep 05 '15 09:09

Shikloshi


2 Answers

For some reason this code worked:

app.run(function($rootScope, $state, $location, UserService){
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
        let loggedIn = UserService.isLoggedIn();
        if  (toState.name !== 'app.login' && !loggedIn){
            $location.url('/login');
        }
    });
});

I changed the way I'm redirecting to the login page from $state.go to $location.url.

Each time I used the $state.go it fired another $stateChangeStart event and this was, apparently, wrong. In this way the event.preventDefault() is not necessary.

like image 192
Shikloshi Avatar answered Oct 24 '22 23:10

Shikloshi


You could use "transitionTo". Replace $location.url('/login'); with $state.transitionTo('login'); ui-router @version v0.2.18

like image 43
Erick Moises Racancoj Amperez Avatar answered Oct 24 '22 22:10

Erick Moises Racancoj Amperez