New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cancelling routes #2109

Closed
geddski opened this Issue Mar 6, 2013 · 14 comments

Comments

Projects
None yet
@geddski
Contributor

geddski commented Mar 6, 2013

There is currently no good/documented way of canceling a route change.

event.preventDefault() can be used with $locationChangeStart but that event doesn't fire from the back button (bug?)

$routeChangeStart does fire on back button, but its preventDefault() method doesn't actually prevent the route from changing (bug?)

Related issues: #592 #665 #1569

@IgorMinar

This comment has been minimized.

Show comment
Hide comment
@IgorMinar

IgorMinar Mar 7, 2013

Member

Locationchangestart event should do the trick if it doesn't then that's a bug. Can you repro this?

Member

IgorMinar commented Mar 7, 2013

Locationchangestart event should do the trick if it doesn't then that's a bug. Can you repro this?

@geddski

This comment has been minimized.

Show comment
Hide comment
@geddski
Contributor

geddski commented Mar 7, 2013

@geddski

This comment has been minimized.

Show comment
Hide comment
@geddski

geddski Mar 7, 2013

Contributor

I'm playing around with simulating a back button in the locationSpec, but it's having no effect on $location.url():

$location.url() // 'somePath'
$window.history.go(-1);
$location.url() // 'somePath' still
$window.history.back();
$location.url() // 'somePath' still

Maybe that's part of the problem.

Contributor

geddski commented Mar 7, 2013

I'm playing around with simulating a back button in the locationSpec, but it's having no effect on $location.url():

$location.url() // 'somePath'
$window.history.go(-1);
$location.url() // 'somePath' still
$window.history.back();
$location.url() // 'somePath' still

Maybe that's part of the problem.

@DanWahlin

This comment has been minimized.

Show comment
Hide comment
@DanWahlin

DanWahlin Apr 13, 2013

Any idea when this will make into one of the "unstable" builds? This is a show stopper when a controller needs to track dirty data and prevent navigation away from a view (or at least prompt the user). Thanks for the fix though quazzie.

DanWahlin commented Apr 13, 2013

Any idea when this will make into one of the "unstable" builds? This is a show stopper when a controller needs to track dirty data and prevent navigation away from a view (or at least prompt the user). Thanks for the fix though quazzie.

petebacondarwin added a commit that referenced this issue May 1, 2013

fix($location): back-button should fire $locationChangeStart
Before $locationChangeStart event is not broadcast when pressing the back-button on the browser.

Closes #2109
@reichertm

This comment has been minimized.

Show comment
Hide comment
@reichertm

reichertm Oct 11, 2013

Contributor

Calling $route.reload() in $routeChangeStart seems to prevent the route from changing.

Contributor

reichertm commented Oct 11, 2013

Calling $route.reload() in $routeChangeStart seems to prevent the route from changing.

@WhatFreshHellIsThis

This comment has been minimized.

Show comment
Hide comment
@WhatFreshHellIsThis

WhatFreshHellIsThis Oct 15, 2013

The event $locationChangeStart has as it's second parameter the 'next' route but all it shows is the full path: "http://localhost:3000/#/users" Surely if you expect people to use this to cancel routes it should include only the /users (for example) part of the path as $routeChangeStart event does with it's 'originalPath' property.

Right now we're forced to parse the URL to use this.

These inconsistencies need to be cleaned up, they make it a nightmare to learn angular.

WhatFreshHellIsThis commented Oct 15, 2013

The event $locationChangeStart has as it's second parameter the 'next' route but all it shows is the full path: "http://localhost:3000/#/users" Surely if you expect people to use this to cancel routes it should include only the /users (for example) part of the path as $routeChangeStart event does with it's 'originalPath' property.

Right now we're forced to parse the URL to use this.

These inconsistencies need to be cleaned up, they make it a nightmare to learn angular.

@nickspacek

This comment has been minimized.

Show comment
Hide comment
@nickspacek

nickspacek Jan 17, 2014

I tried $route.reload in $routeChangeStart but it seems to cause a loop and the page freezes (Angular 1.2.7).

nickspacek commented Jan 17, 2014

I tried $route.reload in $routeChangeStart but it seems to cause a loop and the page freezes (Angular 1.2.7).

@bradgreens

This comment has been minimized.

Show comment
Hide comment
@bradgreens

bradgreens Feb 7, 2014

@nickspacek I had the same problem. I resolved it by injecting $location and calling $location.url('original/path/1') instead of $route.reload() and it worked well. I think this is because by the time the $routeChangeStart event fires, the Angular internals have updated a property to the new route and $route.reload() continuously reloads the new route regardless if you're trying to prevent it from happening.

As @WhatFreshHellIsThis mentioned there are inconsistencies with the arguments for $locationChangeStart and $routeChangeStart. It'd be nice if they were in sync, I wonder if there's a reason to expose the naked URLs for the $locationChangeStart arguments instead of sugared JS objects.

In my case, on $routeChangeStart, I am sniffing the next argument for next.params.id to determine if the user is allowed to access a manually entered URL hash.

The downside to my $location.url() solution is that it triggers a page transition while returning to the same page.

bradgreens commented Feb 7, 2014

@nickspacek I had the same problem. I resolved it by injecting $location and calling $location.url('original/path/1') instead of $route.reload() and it worked well. I think this is because by the time the $routeChangeStart event fires, the Angular internals have updated a property to the new route and $route.reload() continuously reloads the new route regardless if you're trying to prevent it from happening.

As @WhatFreshHellIsThis mentioned there are inconsistencies with the arguments for $locationChangeStart and $routeChangeStart. It'd be nice if they were in sync, I wonder if there's a reason to expose the naked URLs for the $locationChangeStart arguments instead of sugared JS objects.

In my case, on $routeChangeStart, I am sniffing the next argument for next.params.id to determine if the user is allowed to access a manually entered URL hash.

The downside to my $location.url() solution is that it triggers a page transition while returning to the same page.

@zulrang

This comment has been minimized.

Show comment
Hide comment
@zulrang

zulrang Jun 16, 2014

I'm having a similar issue where I want to authenticate the route change by examining the sugared next parameter and cancelling the route change in the case where the user isn't authorized.

This seems like a very basic feature that should have a clean solution.

zulrang commented Jun 16, 2014

I'm having a similar issue where I want to authenticate the route change by examining the sugared next parameter and cancelling the route change in the case where the user isn't authorized.

This seems like a very basic feature that should have a clean solution.

@Darmikon

This comment has been minimized.

Show comment
Hide comment
@Darmikon

Darmikon Jul 2, 2014

event.preventDefault() method in $routeChangeStart event callback still doesn't prevent route change and actually does nothing

$scope.$on('$routeChangeStart',function (event, next, current){
    if(next.originalPath.indexOf('route1')!==-1){
        console.log("I didn't prevent route change");
        event.preventDefault();
    }
});
$scope.$on("$locationChangeStart", function(event, nextUrl, currentUrl) {
    if(nextUrl.indexOf('route1')!==-1){
        console.log('I prevented route change');
        event.preventDefault();
    }
});

Darmikon commented Jul 2, 2014

event.preventDefault() method in $routeChangeStart event callback still doesn't prevent route change and actually does nothing

$scope.$on('$routeChangeStart',function (event, next, current){
    if(next.originalPath.indexOf('route1')!==-1){
        console.log("I didn't prevent route change");
        event.preventDefault();
    }
});
$scope.$on("$locationChangeStart", function(event, nextUrl, currentUrl) {
    if(nextUrl.indexOf('route1')!==-1){
        console.log('I prevented route change');
        event.preventDefault();
    }
});
@OakBehringer

This comment has been minimized.

Show comment
Hide comment
@OakBehringer

OakBehringer Aug 15, 2014

as @zulrang said - I'm trying to do the exact same thing... big time bummer.

OakBehringer commented Aug 15, 2014

as @zulrang said - I'm trying to do the exact same thing... big time bummer.

@notatestuser

This comment has been minimized.

Show comment
Hide comment
@notatestuser

notatestuser Aug 16, 2014

@OakBehringer can't you just add a resolve dep that runs the check in routes that require authentication? as an added bonus you can offer your user object to the controller.

notatestuser commented Aug 16, 2014

@OakBehringer can't you just add a resolve dep that runs the check in routes that require authentication? as an added bonus you can offer your user object to the controller.

@bradgreens

This comment has been minimized.

Show comment
Hide comment
@bradgreens

bradgreens Aug 17, 2014

We do this. I added a provider which the resolve property of the router utilizes. It tests a variety of auth conditions and either redirects the user to their destination or back to the login screen. We apply this provider to all routes and use API header authentication, combined with Rails sessions to allow a session to persist over multiple visits. At least... I think that's what we have, I'm definitely a UI guy.

bradgreens commented Aug 17, 2014

We do this. I added a provider which the resolve property of the router utilizes. It tests a variety of auth conditions and either redirects the user to their destination or back to the login screen. We apply this provider to all routes and use API header authentication, combined with Rails sessions to allow a session to persist over multiple visits. At least... I think that's what we have, I'm definitely a UI guy.

@alexey-sh

This comment has been minimized.

Show comment
Hide comment
@alexey-sh

alexey-sh Nov 3, 2016

Nothing helps me for v0.2.18.

alexey-sh commented Nov 3, 2016

Nothing helps me for v0.2.18.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment