Ionic 4 tabs navigation post login - Solution

Hi ,

Seen so many post regarding navigation to tabs page from login page, here is an working example.

Create a ionic 4 project using - ionic start Sample tabs --type=angular.

Add a page called login - ionic g page login

And copy paste the below code page wise -

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    loadChildren: './login/login.module#LoginPageModule'
  },
  {
    path: 'app',
    loadChildren: './tabs/tabs.module#TabsPageModule'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

tabs.page.html

<ion-tabs>
  <ion-tab label="Home" icon="ios-notifications" href="/app/tabs/(home:home)">
    <ion-router-outlet name="home"></ion-router-outlet>
  </ion-tab>
  <ion-tab label="About" icon="information-circle" href="/app/tabs/(about:about)">
    <ion-router-outlet name="about"></ion-router-outlet>
  </ion-tab>
  <ion-tab label="Contact" icon="contacts" href="/app/tabs/(contact:contact)">
    <ion-router-outlet name="contact"></ion-router-outlet>
  </ion-tab>
</ion-tabs>

Simply i have created a event on login page from where i simply navigating to tabs page -


**login.page.html**

<ion-header>
  <ion-toolbar>
    <ion-title>login</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding>
<ion-button (click)="navTabs()" expand="block">Navigate to tabs</ion-button>
</ion-content>

**login.page.ts**
async navTabs(){
    //you can use either of below
    this.route.navigateByUrl('/app/tabs/(home:home)');
    //this.navCtrl.navigateRoot('/app/tabs/(home:home)')
}

Screenshot -
login

7 Likes

Hi,

Just change navPage() to navTabs() and it works perfectly.

Thank’s a lot

Hey, I did just like you said, however when I click the button I get an error “navTabs is not a function”.

I already had some pages/tabs set up, so insead of generating a new login page I used the already there home page.

Here is what I have now.

my app-routing.module.ts:

import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";

const routes: Routes = [
  {
    path: "",
    loadChildren: "./home/home.module#HomePageModule"
  },
  {
    path: "app",
    loadChildren: "./tabs/tabs.module#TabsPageModule"
  },
  {
    path: "dashboard",
    loadChildren: "./dashboard/dashboard.module#DashboardPageModule"
  },
  {
    path: "add-items",
    loadChildren: "./add-items/add-items.module#AddItemsPageModule"
  },
  {
    path: "deep",
    loadChildren: "./deep/deep.module#DeepPageModule"
  }
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

my home.page.html:

<ion-header color="primary">
  <ion-toolbar>
    <ion-title>Home</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding>
  <ion-button (click)="navTabs()" expand="block">Go to Dashboard</ion-button>
</ion-content>

and lastly my home.page.ts:

import { Component } from "@angular/core";
import { async } from "q";

async navTabs() {
  this.route.navigateByUrl("/app/tabs/dashboard:dashboard");
}

@Component({
  selector: "app-home",
  templateUrl: "home.page.html",
  styleUrls: ["home.page.scss"]
})
export class HomePage {}

note: when I use async (which, admittedly, i am not farmiliar with) I get an issue in vs code. it is looking for a ; that i don’t know where to put. I tried replacing async with function navTabs() which got rid of the issue, but still doesn’t work

when I serve the app it lands on the home page, but clicking on the button just gives this error:

ERROR TypeError: "_co.navTabs is not a function"
	View_HomePage_0 ng:///HomePageModule/HomePage.ngfactory.js:27:27
	handleEvent http://localhost:8100/vendor.js:41372:41
	callWithDebugContext http://localhost:8100/vendor.js:42465:22
	debugHandleEvent http://localhost:8100/vendor.js:42168:12
	dispatchEvent http://localhost:8100/vendor.js:38831:16
	renderEventHandlerClosure http://localhost:8100/vendor.js:39275:38
	decoratePreventDefault http://localhost:8100/vendor.js:57167:36
	invokeTask http://localhost:8100/polyfills.js:2743:17
	onInvokeTask http://localhost:8100/vendor.js:34932:24
	invokeTask http://localhost:8100/polyfills.js:2742:17
	runTask http://localhost:8100/polyfills.js:2510:28
	invokeTask http://localhost:8100/polyfills.js:2818:24
	invokeTask http://localhost:8100/polyfills.js:3862:9
	globalZoneAwareCallback http://localhost:8100/polyfills.js:3888:17
HomePage.html:8:2
ERROR CONTEXT 
Object { view: {…}, nodeIndex: 9, nodeDef: {…}, elDef: {…}, elView: {…} }
HomePage.html:8:2
View_HomePage_0
HomePage.html:8:2
proxyClass
compiler.js:10173
./node_modules/@angular/core/fesm5/core.js/DebugContext_.prototype.logError
core.js:11306
./node_modules/@angular/core/fesm5/core.js/ErrorHandler.prototype.handleError
core.js:1724
dispatchEvent
core.js:7714
renderEventHandlerClosure/<
core.js:8154:29
decoratePreventDefault/<
platform-browser.js:988
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask
zone.js:421
onInvokeTask
core.js:3811
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask
zone.js:420
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask
zone.js:188
./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask
zone.js:496
invokeTask
zone.js:1540
globalZoneAwareCallback

Not sure what i’m doing wrong :frowning: any help would be appreciated, thanks.

I don’t know how your code got compiled it should not as you should put your function inside main class ( HomePage ) at least it did not compile for me, can you try below an let know-

Also put ionic info if below does not work.

home.page.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-home",
  templateUrl: "home.page.html",
  styleUrls: ["home.page.scss"]
})
export class HomePage {
  async navTabs() {
    this.route.navigateByUrl("/app/tabs/dashboard:dashboard");
  }
}

Nice, thanks for the prompt response!!

I moved the function to inside the main class, which got rid of all the issues i was having before, but I now get

{
	"resource": "/Users/nglhubbrich/projects/Sarcan/apps/earthSaverStats/src/app/home/home.page.ts",
	"owner": "typescript",
	"code": "2339",
	"severity": 8,
	"message": "Property 'route' does not exist on type 'HomePage'.",
	"source": "ts",
	"startLineNumber": 13,
	"startColumn": 10,
	"endLineNumber": 13,
	"endColumn": 15
}

I tried importing routes and routermodule thinking that was the issue, but it still has that error.

home.page.ts

import { Component } from "@angular/core";
import { async } from "q";
import { RouterModule, Routes } from "@angular/router";

@Component({
  selector: "app-home",
  templateUrl: "home.page.html",
  styleUrls: ["home.page.scss"]
})
export class HomePage {
  async navTabs() {
    this.route.navigateByUrl("/app/tabs/dashboard:dashboard");
  }
}

> ionic info
✔ Gathering environment info - done!

Ionic:

   ionic (Ionic CLI)             : 4.2.1 (/usr/local/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.0.0-beta.13
   @angular-devkit/build-angular : 0.8.5
   @angular-devkit/schematics    : 0.8.5
   @angular/cli                  : 6.2.5
   @ionic/angular-toolkit        : 1.0.0

Cordova:

   cordova (Cordova CLI) : not installed
   Cordova Platforms     : not available
   Cordova Plugins       : not available

System:

   NodeJS : v8.11.2 (/usr/local/bin/node)
   npm    : 5.6.0
   OS     : macOS

You are missing parentheses for the routes -

Wrong  -  this.route.navigateByUrl("/app/tabs/dashboard:dashboard");
Use Instead -  this.route.navigateByUrl("/app/tabs/(dashboard:dashboard)");

Oh wow! that’s pretty silly of me haha!!

I also had to use this.router instead of this.route but it works all the same now!

Now I just have to figure out how to turn that button into and actual login authentication haha!!

Thank you so much for your help. I am (super) new to ionic and angular so I’m learning on the fly, you’ve been awesome! thank you!

getting error
property ‘route’ does not exist on type ‘Loginpage’.

imported router module but not able to fix. please help.

how you fix that ?
please share the solution.

Paste your LoginPage html and ts here.

Share your code to help you with your problem

Found answer here: Navigation Changes

–>

const routes: Routes = [
{ path: 'login', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'signup', loadChildren: './signup/signup.module#SignupPageModule' }
{ path: '', redirectTo: 'login', pathmatch:'full'},
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' }, // <--- Important
]

the order is important too, you have to place it at the very bottom because it will match any path and the router selects the page with a first found algorithm

7 Likes

Hi
i am getting this error when i click the button

ERROR Error: Uncaught (in promise): TypeError: Cannot read property ‘navigateByUrl’ of undefined
TypeError: Cannot read property ‘navigateByUrl’ of undefined
at LoginPage. (login.page.ts:12)

*** login.page.ts ***

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {

  async navTabs(){
      //you can use either of below
      this.route.navigateByUrl('/app/tabs/(tab1:tab1)');
      //this.navCtrl.navigateRoot('/app/tabs/(tab1:tab1)')

  }

  constructor() { }

  ngOnInit() {}


}

*** app-routing.module.ts ***

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: '', loadChildren: './login/login.module#LoginPageModule' },
  { path: 'register', loadChildren: './register/register.module#RegisterPageModule' },
  { path: 'app', loadChildren: './tabs/tabs.module#TabsPageModule' }


];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

*** login.page.html ***

<ion-header >
  <ion-toolbar color="primary">
    <ion-title style="color: #ffffff;">
      Sign in
    </ion-title>
  </ion-toolbar>
</ion-header>
<ion-content color="primary">
  <ion-card color="light">
    <ion-img src="/assets/cenr.jpg"></ion-img>
    <ion-card-header style="text-align: center">
        <ion-card-title style="color: #0074D9;">IOT BatMeter</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      <ion-item>
        <ion-input required type="email" placeholder="Email"></ion-input>
      </ion-item>
      <ion-item>
        <ion-input required type="password" placeholder="Password"></ion-input>
      </ion-item>
      <div padding style="text-align: center">
        <ion-button (click)="navTabs()" shape="round" color="primary" fill="outline"><ion-icon name="key"></ion-icon> Sign in</ion-button>
      </div>
      <div style="text-align: center;padding: 3px;">
        <ion-button (click)="signOut()" size="small" shape="round" color="primary" fill="outline"><ion-icon name="create"></ion-icon> Sign up</ion-button>
      </div>
      <ion-button (click)="navTabs()" expand="block">Navigate to tabs</ion-button>
    </ion-card-content>
</ion-card>

</ion-content>

please help
best regards

import router into login page and define it into constructor to use it, for more follow the instruction given in the example.

Thank You so much! I’ve been trying since hours to get my navigation doing what I want it to do.
Did not get the idea of order-importance!
made my day!

1 Like

it works thanks a lot

Such a relief … have been working on this for a long time

Hey! Great tutorial bro, appreciate it. Although I have a slight problem in regards to login.page.ts . There seems to be a problem this.routes.navigateByUrl(’/app/tabs/(home:home)’); Keeps telling me that "Propery ‘route’ does not exist on type ‘LoginPage’. Help please. Kind of new here in ionic.

login.page.ts

import { Component, OnInit } from '@angular/core';
import { RouterModule, Routes, Router } from '@angular/router';
import { async } from "q";
@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {

  constructor() { 
    
  }

  ngOnInit() {
  }

  async navTabs(){
    this.routes.navigateByUrl('/app/tabs/(home:home)');
  }
  

}

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: 'login', loadChildren: './login/login.module#LoginPageModule' },
  {
    path: '',
    loadChildren: './login/login.module#LoginPageModule'
  },
  {
    path: 'app',
    loadChildren: './tabs/tabs.module#TabsPageModule'
  },
  
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

login.page.html

<ion-header>
  <ion-toolbar>
    <ion-title>login</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding>
<ion-button (click)="navTabs()" expand="block">Navigate to tabs</ion-button>
</ion-content>```

@Kyushen - Declare the component into constructor, like below.

constructor(private routes: Router) { }

We always need to declare it first into constructor before using any components. :slight_smile:

I have the same problem, always get this error. what caused the problem?Thank you all!

core.js:15714 ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'app/tabs’
Error: Cannot match any routes. URL Segment: 'app/tabs’
at ApplyRedirects.push…/node_modules/@angular/router/fesm5/router.js.ApplyRedirects.noMatchError (router.js:2469)
at CatchSubscriber.selector (router.js:2450)
at CatchSubscriber.push…/node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchSubscriber.error (catchError.js:34)
at MapSubscriber.push…/node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error (Subscriber.js:80)
at MapSubscriber.push…/node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error (Subscriber.js:60)
at MapSubscriber.push…/node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error (Subscriber.js:80)
at MapSubscriber.push…/node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error (Subscriber.js:60)
at MapSubscriber.push…/node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error (Subscriber.js:80)
at MapSubscriber.push…/node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error (Subscriber.js:60)
at TapSubscriber.push…/node_modules/rxjs/_esm5/internal/operators/tap.js.TapSubscriber._error (tap.js:61)
at resolvePromise (zone.js:831)
at resolvePromise (zone.js:788)
at zone.js:892
at ZoneDelegate.push…/node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:17280)
at ZoneDelegate.push…/node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push…/node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at drainMicroTaskQueue (zone.js:601)
at ZoneTask.push…/node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:502)
at invokeTask (zone.js:1744)

and login.html is

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>Login</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding >
  <ion-card>
    <ion-item>
      <ion-label position="floating" >Account</ion-label>
      <ion-input  clearInput="true" required="true" type="email"  [(ngModel)]="userLogin.email"></ion-input>
    </ion-item>

    <ion-item>
      <ion-label position="floating">Password</ion-label>
      <ion-input  clearInput="true" required="true" type="password" minlength = 6  [(ngModel)]="userLogin.password"></ion-input>
    </ion-item>

    <ion-item>
      <ion-button class="loginButton" color="primary" expand="full" size="medium" shape="round" (click)="login()" >

        <ion-ripple-effect></ion-ripple-effect>
        <ion-icon slot="start" name="star"></ion-icon>
        login</ion-button>
    </ion-item>
    <ion-item >
      <ion-badge color="secondary" slot="start"  (click)="goAccountForRegister()"> <ion-icon slot="start" name="star"></ion-icon>new account</ion-badge>
      <ion-badge color="secondary" slot="end">forgot password</ion-badge>
    </ion-item>
  </ion-card>

</ion-content>

and login.module.ts is

import { Component, OnInit } from '@angular/core';
import {BasePage} from '../../base/base.page';
import {BaseInterceptor} from '../../http-interceptors/base-interceptor';
import {AuthService} from '../../services/auth.service';
import {ActivatedRoute, Router} from '@angular/router';
import {LoadingController, NavController, ToastController} from '@ionic/angular';
import {HttpClient} from '@angular/common/http';
import {applyRedirects} from '@angular/router/src/apply_redirects';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage extends BasePage implements OnInit {

  private userLogin = {email: 'hubaokun@gmail.com',  password : '123321'}

  constructor(public auth: AuthService,
              public router: Router,
              public nav: NavController,
              public loadingController: LoadingController,
              public toastController: ToastController,
              public http: HttpClient) {
      // @ts-ignore
      super(router,
          nav,
          loadingController,
          toastController,
          http);
  }

  ngOnInit() {
  }

    async login() {
    this.presentLoading();
    this.http.post('/api/iv1/user/login', this.userLogin).subscribe(
        (result) => {
          this.presentToast('login successfully!');
          console.log(result);
            // BaseInterceptor.auth = result;
            this.auth.saveAuth(result);
            // this.nav.navigateForward('/account'); // It can navigate to a single page, but not tabs
            this.router.navigateByUrl('/app/tabs/(tab1:tab1)');
            // this.router.navigate(['/tabs/tab1']);

          },
        err => {
          this.presentToast('login failed!');
        },
        () => {
          console.log('it`s over');
        }
    );
  }


  goAccountForRegister() {
    this.nav.navigateForward('/account');

  }

}

and the tabs.router.module.ts is

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TabsPage } from './tabs.page';

const routes: Routes = [
  {
    path: 'tabs',
    component: TabsPage,
    children: [
      {
        path: 'tab1',
        children: [
          {
            path: '',
            loadChildren: '../tab1/tab1.module#Tab1PageModule'
          }
        ]
      },
      {
        path: 'tab2',
        children: [
          {
            path: '',
            loadChildren: '../tab2/tab2.module#Tab2PageModule'
          }
        ]
      },
      {
        path: 'setting',
        children: [
          {
            path: '',
            loadChildren: '../setting/setting.module#SettingPageModule'
          }
        ]
      },
      {
        path: '',
        redirectTo: '/tabs/tab1',
        pathMatch: 'full'
      }
    ]
  },
  {
    path: '',
    redirectTo: '/tabs/setting',
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [
    RouterModule.forChild(routes)
  ],
  exports: [RouterModule]
})
export class TabsPageRoutingModule {}

app-routing.module.ts is

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import {TabsPage} from './tabs/tabs.page';
const routes: Routes = [
  { path: 'base', loadChildren: './base/base.module#BasePageModule' },
  { path: 'setting', loadChildren: './setting/setting.module#SettingPageModule' },
  { path: 'login', loadChildren: './account/login/login.module#LoginPageModule' },
  { path: 'register/:account/:code', loadChildren: './account/register/register.module#RegisterPageModule' },
  { path: 'account', loadChildren: './account/account/account.module#AccountPageModule' },
  { path: 'forget-password', loadChildren: './account/forget-password/forget-password.module#ForgetPasswordPageModule' },
  { path: '',
    redirectTo: '/login',
    pathMatch: 'full'
  },

  { path: 'app', loadChildren: './tabs/tabs.module#TabsPageModule' }
];
@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {

}

and the basePage is

import { Component, OnInit } from '@angular/core';
import {Router, ActivatedRoute} from '@angular/router';
import {LoadingController, NavController, ToastController} from '@ionic/angular';
import { HttpClient } from '@angular/common/http';
import {AuthService } from '../services/auth.service';

@Component({
  selector: 'app-base',
  templateUrl: './base.page.html',
  styleUrls: ['./base.page.scss'],
})
export class BasePage implements OnInit {


  constructor(public router: Router,
              public nav: NavController,
              public loadingController: LoadingController,
              public toastController: ToastController,
              public http: HttpClient) {
  }


  ngOnInit() {
  }

  async presentLoading() {
    const loading = await this.loadingController.create({
      message: 'Hellooo',
      duration: 2000
    });
    await loading.present();

    const { role, data } = await loading.onDidDismiss();

    console.log('Loading dismissed!');
  }

  async presentLoadingWithOptions() {
    const loading = await this.loadingController.create({
      spinner: null,
      duration: 5000,
      message: 'Please wait...',
      translucent: true,
      cssClass: 'custom-class custom-loading'
    });
    return await loading.present();
  }

  async presentToast(message: string) {
    const toast = await this.toastController.create({
      message: message,
      duration: 2000
    });
    toast.present();
  }

  async presentToastWithOptions(message: string) {
    const toast = await this.toastController.create({
      message: message,
      showCloseButton: true,
      position: 'top',
      closeButtonText: 'Done'
    });
    toast.present();
  }
}