Stumped on navigation in tab template


Can anyone see what I am doing wrong here. In this example I am trying to simply change page by tapping a button:

Here is (some of) the template

<Button text="Change Page" class="btn btn-primary" (tap)="testNav()"></Button>

And the component:

import { AppRoutingModule, ROUTES } from "../app-routing.module";
import { Router } from "@angular/router";
import { RouterExtensions } from 'nativescript-angular/router';
import { ActivatedRoute } from '@angular/router';
    private router: Router, 
    private routerExt: RouterExtensions, 
    private route: ActivatedRoute) {
testNav() {
    this.routerExt.navigate(['../expense'], { relativeTo: this.route });

The routes file:

import { NgModule } from "@angular/core";
import { Routes, Router } from "@angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";

import { QuicksnapComponent } from "./quicksnap/quicksnap.component";
import { HomeComponent } from "./home/home.component";
import { ItemDetailComponent } from "./item-detail/item-detail.component";
import { ExpenseComponent } from "./expense/expense.component";
import { ReportsComponent } from "./reports/reports.component";
import { ReportComponent } from "./reports/report.component";
import { TestComponent } from "./test/test.component";

export const COMPONENTS = [QuicksnapComponent, HomeComponent, ItemDetailComponent, ExpenseComponent, ReportsComponent, ReportComponent, TestComponent];

export const ROUTES: Routes = [
    { path: "", redirectTo: "/(homeTab:home//quicksnapTab:quicksnap//expenseTab:expense//reportsTab:reports//reportTab:report//testTab:test)", pathMatch: "full" },

    { path: "home", component: HomeComponent, outlet: "homeTab" },
    { path: "quicksnap", component: QuicksnapComponent, outlet: "quicksnapTab" },
    { path: "expense", component: ExpenseComponent, outlet: "expenseTab" },
    { path: "reports", component: ReportsComponent, outlet: "reportsTab" },
    { path: "report", component: ReportComponent, outlet: "reportTab" },
    { path: "test", component: TestComponent, outlet: "testTab" },

    { path: "item/:id", component: ItemDetailComponent, outlet: "homeTab" }

    imports: [NativeScriptRouterModule.forRoot(ROUTES)],
    exports: [NativeScriptRouterModule]
export class AppRoutingModule {}

And here is the console error:

JS: ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'expense'
JS: Error: Cannot match any routes. URL Segment: 'expense'
JS:     at ApplyRedirects.noMatchError (file:///data/data/org.nativescript.myApp/files/app/tns_modules/@angular/router/bundles/router.umd.js:1440:16) [angular]
JS:     at CatchSubscriber.selector (file:///data/data/org.nativescript.myApp/files/app/tns_modules/@angular/router/bundles/router.umd.js:1421:29) [angular]
JS:     at CatchSubscriber.error (file:///data/data/org.nativescript.myApp/files/app/tns_modules/rxjs/internal/operators/catchError.js:111:31) [angular]
JS:     at MapSubscriber.Subscriber._error (file:///data/data/org.nativescript.myApp/files/app/tns_modules/rxjs/internal/Subscriber.js:142:26) [angular]
JS:     at MapSubscriber.Subscriber.error (file:///data/data/org.nativescript.myApp/files/app/tns_modules/rxjs/internal/Subscriber.js:116:18) [angular]
JS:     at MapSubscriber.Subscriber._error (file:///data/data/org.nativescript.myApp/...

This is probably very easy but I have been trying to get this working for hours and no joy yet.

Much appreciate any pointers! Let me know if I haven’t provided enough context/code.


I guess you presumed the selected tab index can be changed via router, which is not true. ../expense will take you to /expenses which won’t exists.

Update TabView’s selected index to change tab.


Thanks for responding.

If my TabView is in app.component.html as follows do you have an idea how I can update tabSelectedIndex from quicksnap.component.ts, for example? I can’t use this.tabSelectedIndex.

<TabView androidTabsPosition="bottom" [(ngModel)]="tabSelectedIndex" sdkExampleTitle sdkToggleNavButton>

        *tabItem="{title: 'Home', iconSource: getIconSource('home')}"

        *tabItem="{title: 'Quicksnap', iconSource: getIconSource('browse')}"

        *tabItem="{title: 'Expense', iconSource: getIconSource('search')}"
        *tabItem="{title: 'Reports', iconSource: getIconSource('search')}"

        *tabItem="{title: 'New Report', iconSource: getIconSource('search')}"

        *tabItem="{title: 'Test', iconSource: getIconSource('browse')}"



You can access the TabView from any component as,

import * as app from 'application';
// will return whatever is there in your app component.
const selectedIndex = app.getRootView().selectedIndex;

Or use a Service and declare tabSelectedIndex as BehaviorSubject there.


Thanks! I think I am very nearly there but not quite.

In my TabView I now have

<TabView androidTabsPosition="bottom" [(ngModel)]="selectedIndex"  id="tabview1"  sdkExampleTitle sdkToggleNavButton>

In the component I have

import * as app from 'application';
// will return whatever is there in your app component.
console.log("Root view="+app.getRootView()); // Root view=TabView<tabview1>
const selectedIndex = app.getRootView().selectedIndex;

The last line causes an error

Property 'selectedIndex' does not exist on type 'View'

Another approach I tried was put id=“tabview1” into the TabView, then in the component

var tabview1 ="tabview1");
tabview1.selectedIndex = 1;

which produces error

Property 'selectedIndex' does not exist on type 'ViewBase'

Honestly so difficult to create a link! Any ideas? Thanks.


That’s simply a TypeScript error, cast your root view, (<TabView> app.getRootView()).selectedIndex.


It’s working! I can simply go (for example)

(<TabView> app.getRootView()).selectedIndex=5;

Thanks very much manojdcoder!