Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ionic 4 ionViewDidEnter() didnt triggered after navigated from ion-back-button

I'm having stuck with Ionic apps. My problem is I want to refresh the root page after navigated from the other page by clicking the ion-back-button, I'm trying to use the ionic lifecycle events.

Anyone having issues with the ionViewDidEnter() too (like in my case)? As I know these lifecycle event function, it’s fired when entering a page, before it becomes the active one.

This is DOM elements when the QR page become active:

enter image description here

As you can see there are 2 pages inside <ion-router-outlet>. In my situation, the <app-home-tabs> is the root page. To navigate to the <app-my-qr> page from the root page, I use this.router.navigateByUrl('/my-qr', and then after I click <ion-back-button>, it's removed from the DOM.

enter image description here

The problem is the root page is not refreshed. I cant find the root caused of this problem..

home-tabs.router.module.ts:

enter image description here

like image 234
Snowbases Avatar asked Nov 08 '19 03:11

Snowbases


3 Answers

I got the same issue, and just found a workaround from Ionic team member liamdebeasi: https://github.com/ionic-team/ionic-framework/issues/16834
He explains very well about this situation and provides a workaround. I just copy the code here, for more details please visit the link.

Hi everyone,

I wanted to provide an update regarding the status of this issue. After discussing with the team, we have determined this is not a bug in Ionic Framework; however, we realize there are valid use cases in which developers may want to listen for lifecycle events on an individual tab. Due to this, we have provided a temporary workaround as well as plans for further development.

Why is this not a bug?

When pages transition in Ionic Framework, they fire lifecycle events. For example, going from /page1 to /page2 would fire ionViewWillLeave and ionViewDidLeave events on the Page1 component and ionViewWillEnter and ionViewDidEnter events on the Page2 component. The same logic applies when going from /tabs/tab1 to /tabs/tab2. In both of these scenarios, we are staying within the same parent ion-router-outlet context.

The reported issue occurs when navigating between ion-router-outlet contexts. In this case, we are seeing it when navigating from /tabs/tab1 to /page2. When this transition happens, Tab1 remains the active tab, and the entire tabs context transitions away. As a result, lifecycle events will fire on the root TabsPage component, but not on Tab1.

For many users, this is unexpected because Tab1 visually appears to transition away. However, under the hood, the entire tabs context transitions away.

What is the workaround?

Luckily, there is an easy to use workaround for developers who wish to listen for lifecycle events on individual tab pages:

tabs.page.html

<ion-tabs #tabs (ionTabsDidChange)="tabChange(tabs)">
  ...
</ion-tabs>

tabs.page.ts

import { Component } from '@angular/core';
import { IonTabs } from '@ionic/angular'

@Component({
  selector: 'app-tabs',
  templateUrl: 'tabs.page.html',
  styleUrls: ['tabs.page.scss']
})
export class TabsPage {
  private activeTab?: HTMLElement;

  constructor() {}
  
  tabChange(tabsRef: IonTabs) {
    this.activeTab = tabsRef.outlet.activatedView.element;
  }

  ionViewWillLeave() {
    this.propagateToActiveTab('ionViewWillLeave');
  }
  
  ionViewDidLeave() {
    this.propagateToActiveTab('ionViewDidLeave');
  }
  
  ionViewWillEnter() {
    this.propagateToActiveTab('ionViewWillEnter');
  }
  
  ionViewDidEnter() {
    this.propagateToActiveTab('ionViewDidEnter');
  }
  
  private propagateToActiveTab(eventName: string) {    
    if (this.activeTab) {
      this.activeTab.dispatchEvent(new CustomEvent(eventName));
    }
  }
}
like image 89
Frank Avatar answered Nov 04 '22 19:11

Frank


After a couple of days, I found the root caused and the solution. Actually the problem is the child component won't refresh/reload... there is a child component <app-home> from (home.page.ts) inside the <app-home-tabs> which is can be seen inside the DOM elements.

The ionViewWillEnter() is not triggered in the child components (home.page.ts).

home-tabs.router.module.ts:

enter image description here

After just put this function inside the parent component, which is the home-tabs.page.ts, <app-home-tabs>. It calls the child component to force update itself. Just using the import { Events } from '@ionic/angular';

Parent component:

async ionViewDidEnter() {
    // This will be called everytime the page become active
    console.log('UpdateHome');
    this.events.publish('UpdateHome');
    ...
}

And inside the child component:

ionViewWillEnter() {
  this.events.subscribe('UpdateHome', async () => {
      console.log('UpdateHome');
      // Update itself
      let loading = await this.loadctrl.create();
      await loading.present();
      await this.getUser();
      this.menuCtrl.enable(true);
      await loading.dismiss();
  });
}
like image 30
Snowbases Avatar answered Nov 04 '22 17:11

Snowbases


Please try this . Also happen to me recently .

import { ViewChild } from '@angular/core';
import { IonBackButtonDelegate } from '@ionic/angular';

...
@ViewChild(IonBackButtonDelegate) backButton: IonBackButtonDelegate;
...

ionViewDidEnter() {
    console.log('ionViewDidEnter');
    this.setUIBackButtonAction();
  }

setUIBackButtonAction() {
this.backButton.onClick = () => {
  // handle custom action here
  console.log('is back on click');
  this.router.navigate(['/home-tabs/home'])
    .then(() => {
      window.location.reload();
    });
}
like image 2
JazzyDefiant Avatar answered Nov 04 '22 17:11

JazzyDefiant