Angular JS $locationChangeStart get next url route object

All we need is an easy explanation of the problem, so here it is.

I am trying to implement Authorization on my angular application, when a route is changed I want to check whether the route is authorized for user or not. I tried with $routeChangeStart but it does not prevents the event.

My current code:

$scope.$on('$routeChangeStart', function(event, next, current) {
        if(current_user.is_logged_in){
            var route_object = next.route_object;
            if(!(route_object.route_roles)){
                event.preventDefault();
            }
        }
    });

Here in my next object I am getting route_object which is set in my $routeProvider

var routes = object;
    app.config(function($routeProvider) {
                $routeProvider.when(url, {
                    templateUrl: "/users.html",
                    route_object: routes,
                    });
            });

routes is an object which is formed in my function, but when I use $locationChangeStart I am just getting url’s of next and previous page,

How do I get the entire route object??

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You can get the route parameter in an $locationChangeStart event listener like this:

$scope.$on('$locationChangeStart', function(event, next, current) {
    if(current_user.is_logged_in){
        var route_object = ($route.routes[$location.path()]).route_object; //This is how you get it
        if(!(route_object.route_roles)){
            event.preventDefault();
        }
    }
});

Then classic preventDefault method would do the work. Here’s a plunker that I wrote for something similar.

Method 2

    $routeProvider
        .when('/', {
            title: 'Home',
            templateUrl: 'partials/home',
            controller: 'HomeController',
            access: {
                isFree: true
            }
        })
        .when('/about-us', {
            title: 'About us',
            templateUrl: 'partials/aboutus',
            controller: 'AboutUsController',
            access: {
                isFree: true
            }
        })
        .when('/how-it-works', {
            title: 'How It Works',
            templateUrl: 'partials/howitworks',
            controller: 'HowItWorksController',
            access: {
                isFree: true
            }
        })
        .when('/login', {
            templateUrl: 'users/login',
            controller: 'LoginController',
            access: {
                isFree: true
            }
        })
        .when('/logout', {
            controller: 'LogoutController',
            access: {
                isFree: false
            }
        })
        .when('/sign-up', {
            templateUrl: 'users/signup',
            controller: 'SignUpController',
            access: {
                isFree: true
            }
        })
        .otherwise({
            redirectTo: '/'
        });
})


.run(['$rootScope', '$location','$log','$window','Auth' ,function($rootScope, $location, $log, $window, Auth) {

    $rootScope.$on('$routeChangeStart', function(event, currRoute, prevRoute){
        $rootScope.title = '';
        if(currRoute.$$route.title !== undefined){
            $rootScope.title = currRoute.$$route.title ;
        }
      //  $rootScope.userLoggedIn = {name : 'Hi, '+ 'Amar'}    

        let checkIsLoggedInForRoute = ['/login','/sign-up'];
        let isFreeAccess = currRoute.$$route.access.isFree;
        let isLoggedIn = Auth.isLogin();

        if(isFreeAccess){
            if(checkIsLoggedInForRoute.indexOf($location.path()) !== -1 && isLoggedIn){
                event.preventDefault();
                $location.path('/')   
            }
        }else if(!isFreeAccess){
            let isLogoutRoute = currRoute.$$route.originalPath.indexOf('/logout') !== -1;
            if(isLogoutRoute && isLoggedIn){
                Auth.logout();           
                $location.path('/');    
            }else if(isLogoutRoute && !isLoggedIn){ 
                $location.path('/login');
            } 
        }
    });
}]);

Method 3

What is contained in next.$$route?

There should be a next.$$route.route_object

Method 4

You can also use $location provider to do this like :

.run(['$rootScope','$location',function($rootScope,$location){
      $rootScope.$on('$routeChangeStart', function(event,next, current) {
       console.log('next',next);
       console.log('location',$location.path());
       console.log('location',$location.search()); // for route params
     });
    }])`

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply