Angular JS $locationChangeStart get next url route object
Asked Answered
Y

4

11

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??

Yorke answered 31/10, 2014 at 12:28 Comment(0)
L
21

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.

Lys answered 31/10, 2014 at 13:55 Comment(3)
This is actually working for me but the issue is $location.$$path returns /users but inside my route I have URL as /users/:id? Because of which I am getting an error.Yorke
This doesn't work. If $location.path is /user/10 then the route /user/:id can't be found.Lobbyism
fyi if you're using ui.router, you will need to use $stateChangeStart.Toxic
B
1
    $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');
            } 
        }
    });
}]);
Brahmin answered 12/4, 2017 at 7:38 Comment(2)
Hi and welcome to StackOverflow! How does this answer improve the already existing, accepted answer?Sparky
You can improve the Quality of this Answer by adding a description of how this answer works and thus how it improves the Questioner's situation.Wittenberg
R
0

What is contained in next.$$route?

There should be a next.$$route.route_object

Route answered 31/10, 2014 at 12:38 Comment(5)
Inside $locationChangeStart next is just a string.Yorke
No, don't use $locationChangeStart... $routeChangeStart is where you want to be: $scope.$on('$routeChangeStart', function(event, next, current) { console.log(JSON.stringify(next.$$route, null, 4)); if(current_user.is_logged_in){ var route_object = next.$$route.route_object; if(!(route_object.route_roles)){ event.preventDefault(); } } });Route
Yaa that works, but I cannot prevent the event inside $routeChangeStartYorke
There doesn't seem to be a way to negate the event (as you're inside a function that was fired from a broadcast) ... but I found this that might help: linkRoute
Sorry, your question was: How do I get the entire route object?? That's all I tried to answer...Route
P
0

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
     });
    }])`
Pedestrianize answered 16/12, 2016 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.