-
Notifications
You must be signed in to change notification settings - Fork 27.5k
URL out of sync with ng-view after a $routeChangeError #2100
Comments
Does anyone have a decent solution for this problem? |
It would be great if this could be fixed somewhere along the line... |
+1 |
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:
|
Just a note: the above code won't work for routes with parameters, |
Oh I didn't notice that, thank you. Here's a little fix, I don't know how to do this the Angular way: previous.originalPath.replace(/:(\w+)/g, (match, param) -> previous.pathParams[param]) |
+1 need a clean solution too |
In case of rejected resolve on route change: there is a needless entry in the history and a wrong location is shown. Any ideas? |
I can't believe not finding a solution for that issue. In my case i don't want to redirect to error pages, so i want to stay in the current view. Is route resolve simply unusable? What i'm overlooking? |
What about to show route defined as |
For now i redirect to an error view, though i'd like to handle route change errors messages via popup or something like that. |
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. |
@just-boris I use angular-http-auth and |
Very interesting. +1 for the route reload usage.
My scheme ideally covers this case |
👍 |
1 similar comment
+1 |
Any update on this? |
severity: inconvenient !! is there a proper way to not having a wrong route in history, though resolve fails before route change? |
👍 |
Building on @just-boris and @dogancelik comments, I'm using this code and it works good: $rootScope.$on("$routeChangeError", function(event, current, previous, rejection) {
if (previous) {
$window.history.back();
} else {
$location.path("/").replace();
}
}); (assumes "/" is your default route) |
This really is the worst! I'm having to write completely insane things to work around this. Can we get this in a 1.4.x milestone maybe? |
This needs to be addressed in 1.4.x, I think. |
I think it might be that this is a good use case for the "location change without route change" issue. |
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. |
@Tathanen could you please show us some of your code. The important bits, that work for you? So we can maybe get some clues how to change this... |
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
Where 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 |
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.
The text was updated successfully, but these errors were encountered: