Ionic 4 - Nested Tabs Relative Routes

HI
I have an app that has two sets of tabs, one off the main home page

<ion-tab-bar slot="bottom">
	<ion-tab-button *ngFor="let tab of tabs" tab="{{tab.name}}">
		<ion-icon name="{{tab.icon}}"></ion-icon>
		<ion-label>{{tab.name|titlecase}}</ion-label>
	</ion-tab-button>
</ion-tab-bar>

const routes: Routes = [{
	path: '',
	component: HomePage,
	children: [
		{ path: '', redirectTo: 'prospecting', pathMatch: 'full' },
		{ path: 'prospecting', children: [{ path: '', loadChildren: './prospecting/prospecting.module#ProspectingPageModule' }] },
		{ path: 'approvals', children: [{ path: '', loadChildren: './approvals/approvals.module#ApprovalsPageModule' }] },
		{ path: 'interactions', children: [{ path: '', loadChildren: './interactions/interactions.module#InteractionsPageModule' }] },
		{ path: 'bookings', children: [{ path: '', loadChildren: './bookings/bookings.module#BookingsPageModule' }] }
	]
}];

The above all works 100% and the associated tabs all style correctly, highlighting the active tab associated with the relevant route.

I have a second set of tabs nest within one of my child routes

<ion-tab-bar slot="top">
	<ion-tab-button [routerLink]="['web']" layout="icon-end">
		<ion-icon name="globe"></ion-icon>
		<ion-label>Web</ion-label>
	</ion-tab-button>

	<ion-tab-button [routerLink]="['old-companies']" layout="icon-end">
		<ion-icon name="briefcase"></ion-icon>
		<ion-label>Old Companies</ion-label>
	</ion-tab-button>

	<ion-tab-button [routerLink]="['itc']" layout="icon-end">
		<ion-icon name="filing"></ion-icon>
		<ion-label>ITC</ion-label>
	</ion-tab-button>

	<ion-tab-button [routerLink]="['external']" layout="icon-end">
		<ion-icon name="business"></ion-icon>
		<ion-label>External</ion-label>
	</ion-tab-button>
</ion-tab-bar>

const routes: Routes = [{
	path: '',
	component: ProspectingPage,
	children: [
		{ path: '', redirectTo: 'web', pathMatch: 'full' },
		{ path: 'web', children: [{ path: '', loadChildren: './web/web.module#WebPageModule' }] },
		{ path: 'old-companies', children: [{ path: '', loadChildren: './old-companies/old-companies.module#OldCompaniesPageModule' }] },
		{ path: 'itc', children: [{ path: '', loadChildren: './itc/itc.module#ItcPageModule' }] },
		{ path: 'external', children: [{ path: '', loadChildren: './external/external.module#ExternalPageModule' }] }]
}];

I can only get the nested tabs to work by using “[routerLink]” as when I just use the tab=“name” property my application does not keep the route relative and attempts to overwrite the route from the home page and comes up with routing errors, that being said the above all works except for the fact now when navigating around the nested paths the relevant tabs don’t display in an activated state and always appear is if they are not selected, if I use the tab=“name” property on first load everything loads correctly and the tab shows activated as the route matches the name, but you can’t click the actual tabs without causing an error.

Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment

Is there a way to either use the “[routerLink]” and show the correct activated tab style or use the tab=“name” property and have the route resolve relative to it’s current location?

2 Likes
<ion-tab-button (click)="clickTab($event, 'external')" [routerLink]="['external']" tab="external" layout="icon-end">
    <ion-icon name="business"></ion-icon>
    <ion-label>External</ion-label>
</ion-tab-button>
clickTab(event: Event, tab: string) {
	event.stopImmediatePropagation();
	this.router.navigate([`${this.tabPath}${tab}`]);
}
2 Likes

Hi, i am facing exactly the same problem. Did you manage to make it work?

Hi

Yes, I’ve posted my solution on the forum, not sure if you’ve seen it.

Basically I’m just preventing the click and manually setting the route in code, works well with all the correct styling on the tabs,

let me know if you come right.

Thanks @aharonDLis. It worked for me, but i still do not understand why this worked fine in ionic 3, and now we need to add your solution for ionic 4.

I am facing the same issue here. I am currently on “/tabs/tab2” route and trying to click on “discover” tab which will lead to “tabs/tab2/discover” view

I am using following code

<ion-tabs>
    <ion-tab-bar slot="top" color="dark">
      <ion-tab-button *ngFor="let tab of subtabs" tab="tab2/{{tab.name}}">
        <ion-label>{{tab.name|uppercase}}</ion-label>
      </ion-tab-button>
    </ion-tab-bar>
  </ion-tabs>

const routes: Routes = [{
  path: '',
  component: Tab2Page,
  children: [
    {path: '', redirectTo: 'tab2', pathMatch: 'full'},
    {path: 'discover', children: [{path: '', loadChildren: '../subtabs/discover/discover.module#DiscoverPageModule'}]},
    {path: 'popular', children: [{path: '', loadChildren: '../subtabs/popular/popular.module#PopularPageModule'}]}
  ]
},
{path: '', redirectTo: 'tab2', pathMatch: 'full'},
];

also used the code suggested by @aharonDLis result was same error.

can someone suggest better option??

1 Like

Hi

It appears you’re not using the click event to stop propagation and setting the navigation path in code

				<ion-tab-button (click)="clickTab($event, 'web')" [routerLink]="['web']" tab="web" layout="icon-start">
					<ion-icon name="globe"></ion-icon>
					<ion-label>Web</ion-label>
				</ion-tab-button>

	clickTab(event: Event, tab: string) {
		event.stopImmediatePropagation();
		this.router.navigate([`${this.tabPath}${tab}`]);
	}

As I have mentioned. Your code doesn’t worked for me. I was getting same error I am getting right now. see the implementation below.

<ion-tabs>
    <ion-tab-bar slot="top" color="dark">
      <ion-tab-button (click)="clickTab($event, 'discover')" [routerLink]="['discover']" tab="discover" layout="icon-start">
        <ion-label>DISCOVER</ion-label>
      </ion-tab-button>
      <ion-tab-button (click)="clickTab($event, 'popular')" [routerLink]="['popular']" tab="popular" layout="icon-start">
        <ion-label>POPULAR</ion-label>
      </ion-tab-button>
    </ion-tab-bar>
  </ion-tabs>
clickTab(event: Event, tab: string) {
    event.stopImmediatePropagation();
    console.log( event, tab );
    // this.router.navigate([`${this.tabPath}${tab}`]);
  }

This is what you are suggesting? its not working…

also "tabPath" in line this.router.navigate([{this.tabPath}{tab}]); is unrecognised

1 Like

Thank you man… it worked at last

Hi @mrbhaskar ,
Could you please help me to resolve what is “tabPath” in the code because it is unrecognised for me.

The tabPath is just a local variable that keeps the url path of the current section e.g. “private tabPath = ‘private/interaction/customers/’;”
The tab part is just the sub section so the full path would resolve to “private/interaction/customers/search’;”

Thank a lot @aharonDLis

I am also experiencing this issues. i have notified support but no telling how long it will take for a response.

What is it that you are struggling with sir?

Trying to use nested tabs with the native support. tab=“tab3” when nested directs to the right page but with errors

Not that you need care one iota about my opinion or that of the folks who wrote Tabs, Used Right, but I always do my best to follow the guidelines in that piece when dealing with tabs, and #10 specifically discourages nested tabs on two distinct grounds.

Stick to only one row of tabs. Multiple rows create jumping UI elements, which destroy spatial memory and thus make it impossible for users to remember which tabs they’ve already visited. Also, multiple rows are a sure symptom of excessive complexity: If you need more tabs than will fit in a single row, you must simplify your design.

This is not the scenario we are dealing with, the tabs are not two rows, they are totally separate sections on the site, the initial section with laets say a companies/people/reports

and sub section s of each of thoes placed at the top, organisation[lists/clniics/banks/etc]…

and the tabs are highllighted to indicate I’m on organisations bottom and the top tab ligghts up for it’s relevant sections…

@aharonDLis Your solution is working fine. But it has one issue. i.e. it doesn’t maintain the previous state of the tab. e.g. let’s say we have 2 pages on inner tab call Stores. So user can move to 2nd page and after that he clicks the other inner tab call Brands. Then he come back to previous tab page again. i.e. Stores tab. But he cannot see what he was selected 2nd page there. This behavior is not on Root tabs. i.e. it maintains its state properly. Do you have any clue here?

Could you please tell me how to get the “tabPath” variable ? (it’s not shown in the code)