URL from $routeChangeStart route params in angularjs routes
Asked Answered
G

3

9

How would it be possible to get the URL hash fragment from route params in $routeChangeStart.

$scope.$on('$routeChangeStart', function (event, next, current) {
  // trying to get the url hash fragment from <next> param here
  // e.g. to_url_function(next) -> '/my_path/1'
});

Receiving the URL hash fragment would be easy using $locationChangeStart but this is not an option for me.

Geier answered 15/7, 2015 at 15:9 Comment(2)
check this out #11542195Brantley
Thanks. I've seen this before but I don't think it helps on my particular problem.Geier
T
6

dasboe: I think I'm answering your question.

I have a app with an authentication/authorization check in the $routeChangeStart event handler. If not authenticated, I present user with modal login page. I want a successful login to send them to their original destination (Beauty of $routeChangeStart is that it will run again and check authorization after the successful login). I save the path built from the next in a user session service that is injected into the modal login controller.

here is the event handler

//before each route change, check if the user is logged in
//and authorized to move onto the next route
$rootScope.$on('$routeChangeStart', function (event, next, prev) {
    if (next !== undefined) {
        if ('data' in next) {
            if ('authorizedRoles' in next.data) {
                var authorizedRoles = next.data.authorizedRoles;
                if (!SessionService.isAuthorized(authorizedRoles)) {
                    event.preventDefault();
                    SessionService.setRedirectOnLogin(BuildPathFromRoute(next));
                    if (SessionService.isLoggedIn()) {
                        // user is not allowed
                        $rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
                    } else {
                        // user is not logged in
                        $rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
                    }
                }   
            }
        }
    }
});

Here is the function that builds the path from the next object

function BuildPathFromRoute(routeObj)
{
    var path = routeObj.$$route.originalPath;
    for (var property in routeObj.pathParams)
    {
        if (routeObj.pathParams.hasOwnProperty(property))
        {
            var regEx = new RegExp(":" + property, "gi");
            path = path.replace(regEx, routeObj.pathParams[property].toString());
        }
    }
    return path;
}

Notes:

  • I'm not keen on my $$route reliance, but I couldn't find any other way to do it. Maybe I missed something easier. I may be inviting trouble in the long term.
  • The preventDefault() will not work on AngularJS versions before 1.3.7 (see event.preventDefault() not working for routeChangeStart in angularjs app).
  • Standard caveat: This is all client side and subject to abuse. Make sure authentication/authorization happens server side.
  • The next Route object (from the event handler) also has a params property. I'm not sure if I should spin through its properties like I do with pathParams.
Teyde answered 11/8, 2015 at 12:35 Comment(0)
A
0

If you don't want to use hasOwnProperty, you could take advantage of the $$route.keys to get the names of the pathParams fields names:

function getPathFromRoute(routeObj)
{
    var path = routeObj.$$route.originalPath;
    var keys = routeObj.$$route.keys;
    var value;       
    for (var i = 0; i < keys.length; i++) {
        if(angular.isDefined(keys[i]) && angular.isDefined(keys[i].name)){
            value = routeObj.pathParams[keys[i].name];
            var regEx = new RegExp(":" + keys[i].name, "gi");
            path = path.replace(regEx, value.toString());            
        }
    }     
    return path;
}; 
Anchovy answered 27/4, 2016 at 11:46 Comment(0)
M
0

Don't use object fields with $$ prefix like in previously given answers, because it's a prefix used by AngularJS for private properties. Use this method for get url from route (not tested):

    var buildPathFromRoute = function (route) {
    // get original route path
    var path = route.originalPath;
    // get params keys
    var keysLength = route.keys.length;
    for (var i=0; i<keysLength; i+=1) {
        var param = route.keys[i];

        // optional params postfix is '?'
        var postfix = param.optional ? '\\?' : '';

        var replaceString = ':' + param.name + postfix;
        var regex = new RegExp(replaceString, 'g');
        var paramValue = route.params[param.name].toString();

        // replace param with value
        path = path.replace(regex, paramValue);
    }

    path = path.replace(/\:\S+?\??/g, '');
    return path;
};
More answered 13/3, 2017 at 10:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.