Search code examples
angularionic-frameworkionic4

My Hardware 'Back Button Action' is not working in Ionic 4


I am working in my Ionic 4 app and When the user clicks 2 times on the mobile back button, then it should close the app but this is not happening.

This is my app.component.ts:

lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;

constructor(){
this.backButtonEvent();
}

backButtonEvent() {
    document.addEventListener("backbutton", () => { 
      this.routerOutlets.forEach((outlet: IonRouterOutlet) => {
        if (outlet && outlet.canGoBack()) {
            outlet.pop();
        } else if (this.router.url === '/tabs/tab1') {
          if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
            navigator['app'].exitApp(); //Exit from app
            } else {
            this.presentAlertConfirm();
            this.lastTimeBackPress = new Date().getTime();
          }
          // navigator['app'].exitApp(); // work for ionic 4
        }
      });
    });
  }

  async presentAlertConfirm() {
    const alert = await this.alertController.create({
      // header: 'Confirm!',
      message: 'Are you sure you want to exit the app?',
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel',
          cssClass: 'secondary',
          handler: (blah) => {
          }
        }, {
          text: 'Close App',
          handler: () => {
            navigator['app'].exitApp();
          }
        }
      ]
    });

    await alert.present();
  }

This is working when I am on front page(Tab1) and when I am on the other tabs it is not working and not going to the front page.

I think the problem is in my (outlet && outlet.canGoBack()) because this is not working. I am using the tab theme and Can I send the route to the main tab when the user is no other tabs and clicks the hardware back button.

I am using Ionic 4 tab theme.

Any help is much appreciated.


Solution

  • In response to @Raghav comment, I would try it like this:

    lastTimeBackPress = 0;
    timePeriodToExit = 2000;
    @ViewChildren(IonRouterOutlet) routerOutlets: QueryList < IonRouterOutlet > ;
    
    constructor(private platform: Platform) {
      this.backButtonEvent();
    }
    
    backButtonEvent() {
      this.platform.backButton.subscribeWithPriority(0, () => {
        this.routerOutlets.forEach(async(outlet: IonRouterOutlet) => {
          if (this.router.url != '/tabs/tab1') {
            await this.router.navigate(['/tabs/tab1']);
          } else if (this.router.url === '/tabs/tab1') {
            if (new Date().getTime() - this.lastTimeBackPress >= this.timePeriodToExit) {
              this.lastTimeBackPress = new Date().getTime();
              this.presentAlertConfirm();
            } else {
              navigator['app'].exitApp();
            }
          }
        });
      });
    }
    
    async presentAlertConfirm() {
      const alert = await this.alertController.create({
        // header: 'Confirm!',
        message: 'Are you sure you want to exit the app?',
        buttons: [{
          text: 'Cancel',
          role: 'cancel',
          cssClass: 'secondary',
          handler: (blah) => {}
        }, {
          text: 'Close App',
          handler: () => {
            navigator['app'].exitApp();
          }
        }]
      });
    
      await alert.present();
    }