Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Changing $location.path(newUrl) in $routeChangeStart #9607

Closed
DanWahlin opened this issue Oct 14, 2014 · 5 comments
Closed

Changing $location.path(newUrl) in $routeChangeStart #9607

DanWahlin opened this issue Oct 14, 2014 · 5 comments

Comments

@DanWahlin
Copy link

I'm upgrading an app to 1.3.0 and was previously redirecting a user to a login page as needed when $routeChangeStart fired by calling $location.path('/login').

With 1.3.0 I see the ability to call preventDefault() now (nice addition), but that completely shuts off $location redirects (such as to a login view). $location.path('/login') does work (when preventDefault() hasn't been called) but it only changes the browser URL but not the view. What's the recommended way of doing a redirect now to another view within $routeChangeStart?

Here's an example of what I'm trying to do (pretty standard with older versions of Angular):

$rootScope.$on("$routeChangeStart", function (event, next, current) {
    if (next && next.$$route && next.$$route.secure) {
       if (!authService.user.isAuthenticated) {
            //Was calling this but commenting out to keep it simple: authService.redirectToLogin();

            //Changes URL but not the view - goes to original view that I'm trying to redirect
           //away from now with 1.3. Fine with it but interested in understanding the 
           //"proper" way to do it now so login view gets redirected to.
            $location.path('/login'); 

            //event.preventDefault(); //Nice addition! Can't do any redirect when it's called though
        }
    }
});

I'm assuming there's a different technique now for this type of task in 1.3.0?

@tbosch tbosch self-assigned this Oct 14, 2014
@tbosch
Copy link
Contributor

tbosch commented Oct 14, 2014

Here is a workaround:

  1. do event.preventDefault()
  2. do the change to $location inside of a $rootScope.$evalAsync

E.g.

$rootScope.$on("$routeChangeStart", function (event, next, current) {
    if (next && next.secure) {
      event.preventDefault();
      $rootScope.$evalAsync(function() {
        $location.path('/c');
      });
    }
  });

See this plunker: http://plnkr.co/edit/Zg5wIfyHlfcG1XWyOZmC?p=preview

A nicer way would be if the event had a function redirectTo that did this automatically for you.
Leaving this issue open to implement this new feature.

@DanWahlin
Copy link
Author

Perfect - thanks for the quick response Tobias. I completely agree on the redirectTo function but even without that I'm pretty psyched with the preventDefault() support you added so I'm good for now. :-)

@tbosch tbosch modified the milestones: 1.3.1, Backlog Oct 15, 2014
@sylouuu
Copy link

sylouuu commented Oct 17, 2014

Same issue. Thank you for the workaround.

@hatpick
Copy link

hatpick commented Nov 3, 2014

wrapping it in $timeout works too.

@pkozlowski-opensource
Copy link
Member

As noted by @shahata currently we don't have an extension point that would allow us to add new methods to an event, as all the events are created the same way:

event = {

So, implementing a solution suggested by @tbosch would be more involved.

Looking at the @shahata alternative proposal (#9678) right now.

@caitp caitp modified the milestones: 1.3.2, 1.3.3 Nov 7, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.