Search code examples
ionic-frameworkionic2ionic3

Handling hardware Backbutton after a Button inside a Menu opens a Modal


I have an app with a Sidemenu.

On this menu there's a div tappable that opens a Modal which serves me as a pseudo-select box

    let modal = this.modalCtrl.create('SelectPage');

    modal.onDidDismiss(option => {
      this.updateSelection(option);
    });

    modal.present();

The problem is: If the user tap the Backbutton It doesn't (instantly) close the Modal. First it closes the Sidemenu (behind the modal) then If I tap again it closes de Modal.

I thought it should close the Modal first... Any help?


Solution

  • You could override the functionality of the Android back button. This can be done using this.platform.registerBackButtonAction but when you do so you need to add all the functionality of it yourself. This includes the closing of overlay portals (modals, toasts, alerts), popping pages off the nav stack, closing the side menu, closing the app, and going to previous tabs. I have included all of these except for previous tabs. If you want to attempt to do that see https://hackernoon.com/handling-android-back-button-in-ionic-33f7cfbba4b9

    Another resource for getting the modals to close was https://github.com/ionic-team/ionic/issues/6982

    // app.component.ts
    exitToast: Toast;
    lastTimeBackPress = 0;
    timePeriodToExit = 2000;
    
    constructor(public platform: Platform,
              public toastCtrl: ToastController,
              private ionicApp: IonicApp,
              private menu: MenuController) {
        this.initializeApp();
    }
    
    initializeApp() {
       this.platform.ready().then(() => {
          this.platform.registerBackButtonAction(() => {
             if (this.exitToast !== undefined) {
                this.exitToast.dismiss().then(() => {
                   this.closeOpenItem();
                });
             } else {
                this.closeOpenItem();
             }
          });
       });
    }
    
    closeOpenItem() {
       let activePortal = this.ionicApp._loadingPortal.getActive() ||
        this.ionicApp._modalPortal.getActive() ||
        this.ionicApp._toastPortal.getActive() ||
        this.ionicApp._overlayPortal.getActive();
       if (activePortal) {
          activePortal.dismiss();
         activePortal.onDidDismiss(() => {
         });
       } else if (this.menu.isOpen()) {
          this.menu.close();
       } else if (this.nav.canGoBack()) {
          this.nav.pop();
       } else {
          if (new Date().getTime() - this.lastTimeBackPress < 
              this.timePeriodToExit) {
             this.platform.exitApp();
          } else {
             this.exitToast = this.toastCtrl.create({
                message: 'Press back button again to exit',
                duration: 1000,
                position: 'top'
             });
             this.lastTimeBackPress = new Date().getTime();
             this.exitToast.present();
          }
       }
    }