Angularjs ui-router. How to redirect to login page

angular-ui-router, angularjs, config, resolve, state

Solution

The point is, do not redirect if not needed === if already redirected to intended state. There is a working plunker with similar solution

.run(function($rootScope, $location, $state, authenticationSvc) {


    $rootScope.$on( '$stateChangeStart', function(e, toState  , toParams
                                                   , fromState, fromParams) {

        var isLogin = toState.name === "login";
        if(isLogin){
           return; // no need to redirect 
        }

        // now, redirect only not authenticated

        var userInfo = authenticationSvc.getUserInfo();

        if(userInfo.authenticated === false) {
            e.preventDefault(); // stop current execution
            $state.go('login'); // go to login
        }
    });
});

Check these for similar explanation:

- Angular ui router - Redirection doesn't work at all

- How can I fix 'Maximum call stack size exceeded' AngularJS

Problem

I have 4 states: dashboard, dahboard.main, dashboard.minor, login. dashboard is abstract and it is a parent state for .minor and .main states. Below is my code: ``` .state('dashboard', { url: "/dashboard", abstract: true, templateUrl: "views/dashboard.html", resolve: { auth: function ($q, authenticationSvc) { var userInfo = authenticationSvc.getUserInfo(); if (userInfo) { return $q.when(userInfo); } else { return $q.reject({ authenticated: false }); } } }, controller: "DashboardCtrl", data: { pageTitle: 'Example view' } }) .state('dashboard.main', { url: "", templateUrl: "views/main.html", controller: "DashboardCtrl", data: { pageTitle: 'Main view' } }) ``` As you see in dashboard state I have resolve option. By this I would like to redirect user to login page if he is not authorized. For this reason I use special authenticationSvc service: ``` .factory("authenticationSvc", ["$http", "$q", "$window", function ($http, $q, $window) { var userInfo; function login(email, password) { var deferred = $q.defer(); $http.post("/api/login", { email: email, password: password }) .then(function (result) { if(result.data.error == 0) { userInfo = { accessToken: result.data.accessToken }; $window.sessionStorage["userInfo"] = JSON.stringify(userInfo); deferred.resolve(userInfo); } else { deferred.reject(error); } }, function (error) { deferred.reject(error); }); return deferred.promise; } function getUserInfo() { return userInfo; } return { login: login, logout: logout, getUserInfo: getUserInfo }; }]); ``` I check auth value in config : ``` .run(function($rootScope, $location, $state) { $rootScope.$state = $state; $rootScope.$on("routeChangeSuccess", function(userInfo) { consol.log(userInfo); }); $rootScope.$on("routeChangeError", function(event, current, previous, eventObj) { if(eventObj.authenticated === false) { $state.go('login'); } }); }); ``` But unfortunately when I go to my website root or dashboard state I get an empty page. What is wrong with this code? Thanks!

Original source

Related problems