Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS : angular-ui-router always redirects to $urlRouterProvider.otherwise location

I'm trying to create an SPA where you have to be logged in to access almost everything. So naturally, the default screen you see is the login screen. However, after a user has logged in, no matter what the ui-sref is, ui-router redirects to the login page (even when the user is authenticated). Here is my ui-router code:

(function () {
'use strict';
angular
    .module('app', ['ui.router', 'satellizer'])
    .config(function ($stateProvider, $urlRouterProvider, $authProvider, $httpProvider, $provide) {
  
        $httpProvider.interceptors.push(['$q', '$injector', function($q, $injector){
            return {
                responseError: function (rejection) {
                    var $state = $injector.get('$state');
                    var rejectionReasons = ['token_not_provided', 'token_expired', 'token_absent', 'token_invalid'];
                    angular.forEach(rejectionReasons, function (value, key) {
                        if (rejection.data.error === value) {
                            localStorage.removeItem('user');
                            $state.go('auth');
                        }
                    });

                    return $q.reject(rejection);
                },
                response: function(response) {
                    var authorization = response.headers('authorization');
                    if(authorization !== null) {
                        authorization = authorization.substr(7).trim();
                        //console.log(authorization);
                        var $auth = $injector.get('$auth');
                        $auth.setToken(authorization);
                    }
                    return response;
                }
            }
        }]);

        $authProvider.loginUrl = 'mingdaograder/api/authenticate';

        $stateProvider
            .state('users', {
                url: '/users',
                templateUrl: 'views/userView.html',
                controller: 'UserController as user'
            })
            .state('subjects', {
                url: '/users/:user_id/subjects',
                templateUrl: 'views/subjectsView.html',
                controller: 'SubjectsCtrl as subjectsCtrl'
            })
            .state('subject', {
                url: '/users/:user_id/subjects/:subject_id',
                templateUrl: 'views/subjectView.html',
                controller: 'SubjectCtrl as subjectCtrl'
            })
            .state('auth', {
                url: '/auth',
                templateUrl: 'views/authView.html',
                controller: 'AuthController as auth'
            });
            //.state('otherwise', {
            //    url: '*path',
            //    templateUrl: 'views/authView.html',
            //    controller: 'AuthController as auth'
            //});

            //$urlRouterProvider.otherwise('/auth');
            $urlRouterProvider.otherwise(function($injector, $location) {
                console.log("Could not find " + $location);
                $location.path('/auth');
            });
    })
    .run(function ($rootScope, $state, $log) {
        $rootScope.$on('$stateChangeStart', function (event, toState) {
                console.log(toState.name);
            var user = JSON.parse(localStorage.getItem('user'));
            if (user) {
                $rootScope.authenticated = true;
                $rootScope.currentUser = user;
            }
        }
        );
    }
);
})();

Anytime I try to use $state.go(any state name here) or even type the address into the address bar, I am always redirected to the auth state. On the console the message is "Could not find http://localhost/#/" for every single route. I can type in http://localhost/#/users/5/subjects and I get the same message.

Here is one of my controllers doing a redirect:

(function () {
    'use strict';

    angular
        .module('app')
        .controller('AuthController', AuthController);

    function AuthController($auth, $state, $http, $rootScope, $log) {
        var vm = this;

        vm.loginError = false;
        vm.loginErrorText;

        vm.login = function () {
            var credentials = {
                username: vm.username,
                password: vm.password
            };

            $auth.login(credentials).then(function () {
                return $http.get('api/authenticate/user');
            }, function (error) {
                vm.loginError = true;
                vm.loginErrorText = error.data.error;
            }).then(function (response) {
                var user = JSON.stringify(response.data.user);
                localStorage.setItem('user', user);
                $rootScope.authenticated = true;
                $rootScope.currentUser = response.data.user;

                //$log.info('From AuthCtrl: ' + $rootScope.currentUser.id);
                $state.go('subjects', {user_id:$rootScope.currentUser.id});
            });
        }
    }
})();

Any ideas what I'm doing wrong? Thanks a lot for your time.

Update: Ok, I haven't found a way to fix it but I think I may have found a possible cause. It seems to only happen for the routes with parameters. For example, if I go to the users state, whose path is /users, there is no redirect. However, if I go to the subjects state, whose path is /users/:user_id/subjects, it does redirect. It's like the Url matching service can't recognize that /users/5/subjects matches /users/:user_id/subjects, so redirects. Any ideas how to work around this?

like image 962
Brent Parker Avatar asked Aug 08 '15 16:08

Brent Parker


People also ask

What is UrlRouterProvider otherwise?

otherwise(rule: string | RawNg1RuleFunction): UrlRouterProvider. Defines the path or behavior to use when no url can be matched.

What is UI router in AngularJS?

Angular-UI-Router is an AngularJS module used to create routes for AngularJS applications. Routes are an important part of Single-Page-Applications (SPAs) as well as regular applications and Angular-UI-Router provides easy creation and usage of routes in AngularJS.

What is Route provider in angular?

Routing allows us to create Single Page Applications. To do this, we use ng-view and ng-template directives, and $routeProvider services. We use $routeProvider to configure the routes. The config() takes a function that takes the $routeProvider as a parameter and the routing configuration goes inside the function.


1 Answers

I found I didn't have a '/' at the beginning of my initial state url. Every time I navigated to the state, the missing '/' seemed to push it into the stateProvider.otherwise.

state1: 'opportunity'
state1Url : '/opportunity/' <== added initial forward slash to make it work.

state2: 'opportunity.create'
state2Url : 'create/'
like image 158
sarin Avatar answered Oct 13 '22 18:10

sarin