Search code examples
angularjsangularjs-routing

URL from $routeChangeStart route params in angularjs routes


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.


Solution

  • 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.