angular: bug: relative navigation doesn't work inside route guards
I’m submitting a…
[x] Bug report
Current behavior
Inside a route guard, injecting ActivatedRoute
and attempting relative navigation via this.router.navigate(['../sibling'], {relativeTo: this.route})
results in a Error: Cannot match any routes. URL Segment: 'sibling'
Expected behavior
Relative navigation should work normally
Minimal reproduction of the problem with instructions
A stackblitz example of the issue can be seen here: https://stackblitz.com/edit/angular-gitter-k7fjds
What is the motivation / use case for changing the behavior?
- This appears to be a bug
- If a user navigates to a child route and includes a specific queryParam, I’d like to redirect the user to a sibling route. Currently, this does not appear to be possible inside a route guard with relative navigation.
Additional Information
It appears that the ActivatedRoute
injected into a route guard is always an instance of the root route. Inside a route guard, this.router.navigate(['.'], {relativeTo: this.route})
always takes the user back to the root route, rather than navigating them to the same route they are currently on.
Environment
Angular version: 5.0.0
Browser:
- [x] Chrome (desktop) version 64
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 42
- Comments: 15 (8 by maintainers)
Commits related to this issue
- feat(router): allow passing an ActivatedRouteSnapshot for relative link resolution in Router.createUrlTree The relativeTo property of the navigationExtras parameter in the createUrlTree method of the... — committed to daiscog/angular by daiscog 3 years ago
- feat(router): allow passing an ActivatedRouteSnapshot for relative link resolution in Router.createUrlTree The relativeTo property of the navigationExtras parameter in the createUrlTree method of the... — committed to daiscog/angular by daiscog 3 years ago
- feat(router): allow passing an ActivatedRouteSnapshot for relative link resolution in Router.createUrlTree The relativeTo property of the navigationExtras parameter in the createUrlTree method of the... — committed to daiscog/angular by daiscog 3 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` resolves #42191 (Tested directly) resolves #38276 (The test with a guard covers this case) resolves #22763 (Tested dire... — committed to atscott/angular by atscott 2 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` resolves #42191 (Tested directly) resolves #38276 (The test with a guard covers this case) resolves #22763 (Tested dire... — committed to atscott/angular by atscott 2 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` resolves #42191 (Tested directly) resolves #38276 (The test with a guard covers this case) resolves #22763 (Tested dire... — committed to atscott/angular by atscott 2 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` resolves #42191 (Tested directly) resolves #38276 (The test with a guard covers this case) resolves #22763 (Tested dire... — committed to atscott/angular by atscott 2 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` This exposes a new function from the router public API that allows developers to create a `UrlTree` from _any_ `Activat... — committed to atscott/angular by atscott 2 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` This exposes a new function from the router public API that allows developers to create a `UrlTree` from _any_ `Activat... — committed to atscott/angular by atscott 2 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` This exposes a new function from the router public API that allows developers to create a `UrlTree` from _any_ `Activat... — committed to atscott/angular by atscott 2 years ago
- feat(router): Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` This exposes a new function from the router public API that allows developers to create a `UrlTree` from _any_ `Activat... — committed to atscott/angular by atscott 2 years ago
Any update on this issue?
Still having this Issue in Angular 9 … It’s a pity, that there is no priority in fixing this.
I wrote this small utility function that I use in my guard
You can call it the following ways
The first argument that I pass in is
state.url
because that’s the route I want to go to. The returned URL can then be used withthis.router.navigateByUrl(parseUrl(state.url, '../sibling'));
.I might be missing some edge cases but it works for me, so thought I could share it.
The TL;DR for this one is that this is something I would absolutely love to do but will be a breaking change to update
router.createUrlTree
to do it.The implementation for creating a URL tree is really confusing and actually requires that the
ActivatedRoute/ActivatedRouteSnapshot
be part of the current router url. In reality, we should really be able to create a url from anyActivatedRouteSnapshot
, but that requires the shape of theActivatedRoute
/ActivatedRouteSnapshot
to be valid (which is commonly not the case in tests due to stubbing this out).There is maybe an opportunity to introduce this new way of creating the URL as a standalone function exported as public API in the
router
and then later making the breaking change to include it inrouter.createUrlTree
. This would be problematic for discovery and documentation but would at least provide an early opt-in for anyone trying to do this.I am facing the same issue relative routing does not working in guard services? Guys did you get any fix
It really is a pity that this is so hard. Another workaround was mentioned in #28682, but this also doesn’t seem to work anymore with Angular 9:
For me the “expected” solution would be to accept a
RouterStateSnapshot
inRouter.createUrlTree
. From what I can tellsnapshot
property is the only thing from the route that is used anyway: https://github.com/angular/angular/blob/5edeee69dd0a7ffff0790d6f817c95f58914996d/packages/router/src/create_url_tree.ts#L145-L158Called from https://github.com/angular/angular/blob/5edeee69dd0a7ffff0790d6f817c95f58914996d/packages/router/src/create_url_tree.ts#L27
Which in turn is called from https://github.com/angular/angular/blob/9.0.2/packages/router/src/router.ts#L951
@jasonaden (or anyone from the Angular team): This seems like a trivial fix, so I guess im am overlooking something?
The issue seems to be that the current
ActivatedRoute
is being injected and used (which makes sense, seeing as it is the currently activated route), and there isn’t a way to get what will become the active route in anActivatedRoute
format. (the next route is only provided as anActivatedRouteSnapshot
, which can’t be used for relative navigation).