Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Login/Home pages not destroyed when login/logout in Ionic 5 router

My project is in IONIC 5 and Firstore. There are 2 different ion-router-outlet for authenticated (Home) and unauthenticated (Index) routes. Following is the code for dynamically opening the login/home page for users in class app.component.ts.

  this.afAuth.authState.subscribe(user => {
    if (user) {
      this.router.navigateByUrl('home');
    } else {
      this.router.navigateByUrl('index');
    }
  }); 

Flow: Login Page -> (login) -> Home Page -> (logout) -> Login Page. When the Home page is open the Login page is still loaded and in the navigation stack. The ngOnDestroy of the Login page does not execute. After the logout, the Login page opens again but the class constructor and ngOnInit method does not execute. This is causing a lot of issues as the page initialization is not reloading. The same issue happening for flow Home Page -> (logout) -> Login Page -> (login) -> Home Page. How can I destroy the Login page after login and Home page after logout so that those can reload if reopened in the same session?

EDIT:

Following is the routing config:

app-routing.module.ts

const routes: Routes = [
  {
    path: 'home',
    canLoad: [AuthGuard],
    loadChildren: () => import('./home/home.module').then(m => m.HomePageModule)
  },
  {
    path: 'index',
    loadChildren: () => import('./index/index.module').then(m => m.IndexPageModule)
  },
];

Both the Home.html and Index.html has the same following code.

<ion-content>
  <ion-router-outlet></ion-router-outlet>
</ion-content>

index-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: IndexPage,
    children:[
      {
        path: '',
        loadChildren: () => import('../pages/login/login.module').then( m => m.LoginPageModule)
      },
    ]
  }
];

home-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: HomePage,
    children:[
      {
        path: '',
        loadChildren: () => import('../pages/user/user.module').then( m => m.UserPageModule)
      },
.....
Other authenticated pages
]
like image 526
Tapas Mukherjee Avatar asked Jun 10 '20 19:06

Tapas Mukherjee


2 Answers

Easiest solution that would work, you should navigate to the route with "replaceUrl" NavigationExtras

this.router.navigate(['/home'], { replaceUrl: true });

This replaces the current state in the history, and therefore your Login page will be destroyed. Basically it sets a new root.

Reference

like image 147
Chetan Bansal Avatar answered Nov 19 '22 02:11

Chetan Bansal


The seemingly unexpected behavior you are describing is due to Ionic. More specifically, it is due to how Ionic deals with the life of a page.

When you navigate to a new page, Ionic will keep the old page in the existing DOM, but hide it from your view and transition the new page.

...

Because of this special handling, the ngOnInit and ngOnDestroy methods might not fire when you would usually think they should.

ngOnInit will only fire each time the page is freshly created, but not when navigated back to the page. For instance, navigating between each page in a tabs interface will only call each page's ngOnInit method once, but not on subsequent visits. ngOnDestroy will only fire when a page "popped".

Without knowing much about your application, I would suggest using the Ionic Lifecycle events instead of the Angular ones for your page components. It sounds like you can probably just replace ngOnInit with ionViewWillEnter and replace ngOnDestroy with ionViewWillLeave or ionViewDidLeave.

Further down in the documentation is some useful guidance for each lifecycle method

like image 23
Chris Newman Avatar answered Nov 19 '22 04:11

Chris Newman