Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
URL out of sync with ng-view after a $routeChangeError #2100
Because there was no $routeChangeSuccess, the ng-view still contains content for '/goodRoute', but now the URL is changed to the failed route. They are out of sync.
Any attempt to change the URL back to '/goodRoute' in a $routeChangeError event handler would cause the '/goodRoute' to reload, which is not desirable.
One problem this causes is now the user can't retry the action that caused the error. In a mobile application, for example, they may have been experiencing intermittent connection loss. If they retry the same action, the location change events won't fire because the URL isn't changing, and therefore the route won't be reattempted.
I have the same issue. My current solution is:
$rootScope.$on "$routeChangeError", (event, current, previous, rejection) -> $location.path(if not angular.isUndefined(previous) then previous.originalPath else "/")
There are two options here:
What about to show route defined as
The main reason, why I don't use pop-ups for error, it that is when opening page with error by direct link you will see the only small block instead of full-page message.
P.S. Popups is only useful when you have a deal with request without route change, e.g. form submit or pagination. In this case current view may has an unsaved user data, which cannot be lost.
Very interesting. +1 for the route reload usage.
My scheme ideally covers this case
referenced this issue
Mar 23, 2014
referenced this issue
Apr 21, 2015
severity: broken expected use
Sep 8, 2015
History state is manipulated by
The problem is event ordering and how routing subscribes to location change events.
The main problem as I see it is the synchronous nature of location service. Even if we moved route resolves from
The only way (without changing location service to async nature) would be to always cancel route change start event (which also cancels location change process).
So. on route change start we check any any route resolves and prepare queue them with
Maybe this is all just too complicated an we'd be better off changing location service.
Is there any particular reason why
I'm actually using the current implementation to some good end now, rejecting certian routes and loading them as modal dialogs, and the changed URL allows those dialogs to function as history steps and bookmarkable targets. So if this behavior is changed at some point, I hope it's via a property passed into the routeProvider, or that the current functionality is maintained as an option in that way.
Welll, most of my stuff is labyrinthine application code that wouldn't help much, but the thrust is just this:
There are basically only a couple reasons why I'd reject a route via resolve. One, you're trying to go somewhere you're not allowed to. I hide links you shouldn't be clicking based on your access roles so you'll probably be trying to go to it directly. In this case, I reject the route, which would leave the non-allowed route in the URL, but then I redirect immediately to someplace you're allowed to go, which changes the URL. So no problem here.
Two, I've decided that the route you're going to should (in certain circumstances) not load in ngView, but instead in a dialog created by ngDialog. I like doing it this way because it's all just normal anchor links, you can copy the url out of the link, you can right click and open it in a new tab, etc. It's not some weird fake JS link you can't act on in expected ways. So in this case I reject the route, but still have access to the route data, so I pass it into ngDialog (as seen in the example code above). So the dialog is up with its own unique route. I have my app close dialogs on
If Angular didn't change the URL and insert a history state when you reject a route I couldn't do this exactly the same. I could probably still manage to make it work by manually using
Soooo in summary, rejected routes adding a history state with a URL change can be convenient in certain usecases, irrelevant in others, and irritating mainly only in ones where you're providing access to links someone shouldn't be able to act on. So the "easy" fix is to try and predict when a route change will be rejected ahead of time, and not provide links to that route in the first place. Obviously this doesn't work all of the time, particularly when the error is a failed loaded resource or something, but in these instances at the very least you can just throw a