'How to navigate to a new route in Angular
I have a generic header component with the ability to show tabs when these are available as data in the current route (or parent route). The interface to the tabs is simple:
interface TabItem {
tabId: string;
url: string;
}
Tabs are always relative to each other and a router outlet is available outside of the header component where the actual component is rendered. Also, the routing is setup in such a way that a redirect is done to the first tab, e.g. I have the following routes for a knowledge center page:
{
path: 'knowledge-center',
pathMatch: 'prefix',
data: {
tabs: [
{ tabId: 'Home', link: 'home' },
{ tabId: 'Profile', link: 'profile' },
...
],
},
children: [
{ path: '', pathMatch: 'full', redirectTo: 'home' },
{ path: 'home', component: KnowledgeCenterHomeComponent },
{ path: 'profile', component: KnowledgeCenterProfileComponent },
...
],
}
When using full URLs the navigation is no problem. The problem is how to get the actual route to navigate to when a tab is selected. In the header component I have the following code to get an URLTree when the route is changed:
currentUrl: URLTree;
// Get actual URL as the ActivatedRoute is only set on component instantiation
this.routeSubscription = this.router.events.pipe(
filter((event) => event instanceof NavigationEnd),
tap((event) => {
this.currentUrl = this.router.parseUrl((event as NavigationEnd).url);
})
.subscribe();
Now the big question is how can I navigate to the following URL:
currentUrl + "/../" + tab.link
I have tried the following but that doesn't work:
public onTabSelect(tab: TabItem) {
// this.route is not the actual route but the route when the component is initialized
this.router.navigate(`../${tab.link}`, { relativeTo: this.route });
}
So, how can I use the currentUrl (or possibly something else) to navigate to the proper link?
Solution 1:[1]
For now I've come up with the following solution:
public onTabSelect(tab: TabItem) {
// Note that tabs links are always sibling links!
// Get all segments for the primary outlet and remove the last segment
let segments: UrlSegment[] = [...this.currentUrl.root.children[PRIMARY_OUTLET].segments];
segments.pop();
// Create the tab segment and append to the other segments
let tabSegment: UrlSegment = new UrlSegment(tab.link, {});
segments.push(tabSegment);
// Create new URL
let nextUrl = '/' + segments.map((item: UrlSegment) => item.toString()).join('/');
// And navigate to the new URL
this.router.navigate([nextUrl]);
}
This will use the UrlSegments of the current route and drop the last segment as we know that all tabs are siblings.
Next create a new UrlSegment for the tab link. Additional parameters could be added here but that is not (yet) the case in my situation. The new segment is added to the end of the list of segments for the current route.
To create the URL itself we use the UrlSegment.toString() function on each segment (need to check if this will work with parameters, but is not yet necessary) and join these string with the path separator. Also we make sure that the URL is absolute.
Finally we can just navigate to the URL.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Kees de Bruin |
