How do I navigate to a sibling route?
Solution 1
If you are using the new router (3.0.0-beta2), you can use the ActivatedRoute to navigate to relative path as follow:
constructor(private router: Router, private r:ActivatedRoute) {}
///
// DOES NOT WORK SEE UPDATE
goToContact() {
this.router.navigate(["../contacts"], { relativeTo: this.r });
}
Update 08/02/2019 Angular 7.1.0
current route: /department/7/employees/45/sales
the old version will do: /department/7/employees/45/sales/contacts
As per @KCarnaille's comment the above does not work with the latest Router. The new way is to add .parent
to this.r
so
// Working(08/02/2019)
// DOES NOT WORK SEE UPDATE
goToContact() {
this.router.navigate(["../contacts"], { relativeTo: this.r.parent });
}
the update will do: /department/7/employees/45/contacts
Update 12/12/2021 Angular > 10
As @ziz194 mention it, this is how it now works.
constructor(private router: Router, private r:ActivatedRoute) {}
goToContact() {
this.router.navigate(["contacts"], { relativeTo: this.r });
}
Solution 2
The RouterLink directive always treats the provided link as a delta to the current URL:
[routerLink]="['/absolute']"
[routerLink]="['../../parent']"
[routerLink]="['../sibling']"
[routerLink]="['./child']" // or
[routerLink]="['child']"
// with route param ../sibling;abc=xyz
[routerLink]="['../sibling', {abc: 'xyz'}]"
// with query param and fragment ../sibling?p1=value1&p2=v2#frag
[routerLink]="['../sibling']" [queryParams]="{p1: 'value', p2: 'v2'}" fragment="frag"
The navigate()
method requires a starting point (i.e., the relativeTo
parameter). If none is provided, the navigation is absolute:
constructor(private router: Router, private route: ActivatedRoute) {}
this.router.navigate(["/absolute/path"]);
this.router.navigate(["../../parent"], {relativeTo: this.route});
this.router.navigate(["../sibling"], {relativeTo: this.route});
this.router.navigate(["./child"], {relativeTo: this.route}); // or
this.router.navigate(["child"], {relativeTo: this.route});
// with route param ../sibling;abc=xyz
this.router.navigate(["../sibling", {abc: 'xyz'}], {relativeTo: this.route});
// with query param and fragment ../sibling?p1=value1&p2=v2#frag
this.router.navigate(["../sibling"], {relativeTo: this.route,
queryParams: {p1: 'value', p2: 'v2'}, fragment: 'frag'});
// RC.5+: navigate without updating the URL
this.router.navigate(["../sibling"], {relativeTo: this.route, skipLocationChange: true});
Thorsten Westheider
Computer addict since 1981, first computer being a Texas Instruments TI 99/4A (BASIC), followed by Atari 600XL (BASIC/6502 Assembler) and Atari 1040ST (BASIC/68000 Assembler). Abandoned the superior Atari 1040ST when Windows'95 hit and got myself a PC. Taught myself C/C++, switched to Linux when it was still young and lingered there for a while, only to return when Windows had matured some and .NET had arrived. Started developing software in C# and stuck to it for almost a decade. Couldn't stand Javascript, until it dawned on me: "The web always wins." - Scott Hanselman And since the arrival of Angular 2 I think he may actually have a point.
Updated on July 05, 2022Comments
-
Thorsten Westheider almost 2 years
Let's presume I got this router config
export const EmployeeRoutes = [ { path: 'sales', component: SalesComponent }, { path: 'contacts', component: ContactsComponent } ];
and have navigated to the
SalesComponent
via this URL/department/7/employees/45/sales
Now I'd like to go to
contacts
, but as I don't have all the parameters for an absolute route (e.g. the department ID,7
in the above example) I'd prefer to get there using a relative link, e.g.[routerLink]="['../contacts']"
or
this.router.navigate('../contacts')
which unfortunately doesn't work. There may be an obvious solution but I'm not seeing it. Can anyone help out here please?
-
KCarnaille about 7 yearsI'm actually in the same situation, but it doesn't work for me... something has changed since the official release ?
-
Harry Ninh about 7 years@KCarnaille Hmm I'm on @angular/router 3.0.0 (finished, not beta) and it's still working properly. Not sure if they have any breaking changes since then.
-
KCarnaille about 7 years@Harry Ninh It was my fault actually. A simple issue with path structure :) It's working
-
maxime1992 almost 7 yearsHow can we do that from html with
routerLink
? -
Kugel over 6 yearsWhy does navigate behave differently?
-
Jonathan002 over 5 yearsdo you have a working example of the [routerLink] directive working with sibling route? It keeps switching to an absolute route for me if I use [routerLink]="['../sibling']"
-
inorganik about 5 yearsrouter.navigate() requires the first argument to be an array - but none of these work even as an array
-
Paul Johnson about 5 yearsGreat! I have been baffled by this for about an hour.
-
ziz194 almost 5 yearsThis actually shouldn't be solved by
.parent
just remove the ../ and keep just "contacts" in the path, like this:this.router.navigate(["contacts"], { relativeTo: this.r});
-
godhar almost 5 yearsThis is good info. Shame angular don't include USEFUL information like this in their docs, like all will every need is a heroes app. How complex can you make routing? You have a tree, absolute and relative paths, arrgh.
-
Craig over 4 yearsI really dont understand this logic. So RELATIVE to the parent route, we navigate back one level (grandparent), and move forward to contacts. This should give us /department/7/employees/contacts
-
Marian Simonca over 4 years@Jonathan002, same for me. Did you find anything that works?
-
Reactgular about 4 yearsThis answer isn't completely accurate. A path
../something
is relativeTo where the component is rendered in the router tree, but it is not relative to the current route because that could be a route deeper in the route tree from where the[routerLink]
was applied. If you're trying to do a breadcrumb as an example in the header of your page. It will be relative to where that header is rendered, and most likely not what you want. -
macwier about 4 years@Reactgular Then what's the best way to do breadcrumbs? Use
router.createUrlLink
to create an absolute link based on the currentRoute somewhere and use that inside the router link? -
Reactgular about 4 years@Botis I updated my breadcrumbs by listening for changes to
router.events
andNavigationEnd
, then I recursive walkrouter.routerState.snapshot.root
and rebuild the breadcrumb trail from there. I check fordata
attached to route children to see if I should create a breadcrumb for that route, and then I convertactivatedRouteSnapshot.pathFromRoot
into a string as the URL for that crumb. Yes, it's very complicated. Sadly, couldn't find a better way. -
Jandro Rojas about 2 years@Reactgular the answer is in fact accurate. "../something" is a relative path, it will be relative to something. In the case of the [routerLink] directive, if [relativeTo] is not specified, it will be relative to the activated route of the host scope (which has always been the intended behavior). Paths in a breadcrumb should always be absolute.