10

I am facing an issue how to handle the default mobile's back button which checks the confirmation while exiting from the application, if I pressed the back button there should invoke some handler which shows pop-up, for confirm exiting. OR there is any method call registerBackButtonAction()? or is it so how to use it in IONIC 2,? Please help me out. Thanks in Advance.

7 Answers7

26

In app.component.ts

        @ViewChild(Nav) nav: Nav;

        constructor(private platform: Platform, private toastCtrl:   ToastController, private alertCtrl: AlertController) {
            platform.ready().then(() => {
              // Okay, so the platform is ready and our plugins are available.
              // Here you can do any higher level native things you might need

              platform.registerBackButtonAction(() => {


                //uncomment this and comment code below to to show toast and exit app
                // if (this.backButtonPressedOnceToExit) {
                //   this.platform.exitApp();
                // } else if (this.nav.canGoBack()) {
                //   this.nav.pop({});
                // } else {
                //   this.showToast();
                //   this.backButtonPressedOnceToExit = true;
                //   setTimeout(() => {

                //     this.backButtonPressedOnceToExit = false;
                //   },2000)
                // }

                if(this.nav.canGoBack()){
                  this.nav.pop();
                }else{
                  if(this.alert){ 
                    this.alert.dismiss();
                    this.alert =null;     
                  }else{
                    this.showAlert();
                   }
                }
              });
            });

          }

          showAlert() {
          this.alert = this.alertCtrl.create({
            title: 'Exit?',
            message: 'Do you want to exit the app?',
            buttons: [
              {
                text: 'Cancel',
                role: 'cancel',
                handler: () => {
                  this.alert =null;
                }
              },
              {
                text: 'Exit',
                handler: () => {
                  this.platform.exitApp();
                }
              }
            ]
          });
          alert.present();
        }

          showToast() {
            let toast = this.toastCtrl.create({
              message: 'Press Again to exit',
              duration: 2000,
              position: 'bottom'
            });

            toast.onDidDismiss(() => {
              console.log('Dismissed toast');
            });

            toast.present();
          }
nabin
  • 687
  • 4
  • 13
  • Hello Sir, I have followed your lead on exiting the app on hardware back button and it's working like a charm. But the app goes to the background mode and I want to kill the app instead of the previous situation. And the alertCtrl is fired over and over again when I press the hardware button multiple times(Isn't the alertctrl be fired only once and should be disabled afterwards, if there is any way to do that, I'll be glad to have your help on it).Thank you :) – Ankush Thakur Mar 20 '17 at 13:06
  • @AnkushThakur I have made some changes to the code for tackling multiple alerts. Please check it out. – nabin Mar 22 '17 at 07:26
  • @AnkushThakur this.platform.exitApp() is working for exiting the app succesfully for me. Maybe you are missing this in your config file. – nabin Mar 22 '17 at 07:32
  • Where does this.nav come from ? – J. Volkya Aug 06 '17 at 20:58
  • where is this this.nav coming from? – manish kumar Aug 23 '17 at 19:02
  • @nabin: this solution doesn't always work when a page is pushed from inside one of the pages in tabs: https://stackoverflow.com/questions/46757910/handling-android-back-button-in-ionic-3-with-tabs – Ari Oct 15 '17 at 17:28
  • @Ari I have not tried it but https://stackoverflow.com/a/41373775/2538207 should be of help – nabin Oct 18 '17 at 05:35
  • this.alert.present(); – Tzvi Gregory Kaidanov Nov 14 '17 at 21:15
  • I used the same method and it works fine but it has one drawback, if you have any ModalController opened then tapping the hardware back button on Android takes the nav controller to back while still keeping the Modal on top of the existing navigation. – necixy Nov 30 '17 at 12:31
  • how to define var alert here. like a string ? – Anuj Feb 26 '18 at 06:10
16

Ionic latest version 3.xx

app.component.ts file:

import { Platform, Nav, Config, ToastController } from 'ionic-angular';

constructor(public toastCtrl: ToastController, public platform: Platform) {
    platform.ready().then(() => {
        //back button handle
        //Registration of push in Android and Windows Phone
        var lastTimeBackPress = 0;
        var timePeriodToExit  = 2000;

        platform.registerBackButtonAction(() => {
            // get current active page
            let view = this.nav.getActive();
            if (view.component.name == "TabsPage") {
                //Double check to exit app
                if (new Date().getTime() - lastTimeBackPress < timePeriodToExit) {
                    this.platform.exitApp(); //Exit from app
                } else {
                    let toast = this.toastCtrl.create({
                        message:  'Press back again to exit App?',
                        duration: 3000,
                        position: 'bottom'
                    });
                    toast.present();
                    lastTimeBackPress = new Date().getTime();
                }
            } else {
                // go to previous page
                this.nav.pop({});
            }
        });
    });
}
smottt
  • 3,272
  • 11
  • 37
  • 44
Mohamed Arshath
  • 423
  • 5
  • 15
  • 2
    Could you please explain me about this.nav and how to use NavController in app.component.ts – Tejas Jain Sep 20 '17 at 12:40
  • 1
    this solution doesn't always work when a page is pushed from inside one of the pages in tabs: https://stackoverflow.com/questions/46757910/handling-android-back-button-in-ionic-3-with-tabs – Ari Oct 15 '17 at 17:28
  • thanks for the answer i have scenario were i have side menu is also preset becauce of the when i go to home page(tabs page) to some other page using sidemenu my this.nav.getActive(); is showing the child page it is showing only home page as active page any idea to do pop instead of showing the toast on the second page. – Mohan Gopi Dec 21 '17 at 07:04
4

Platform api has a handler registerBackButtonAction.

You can do something like:

In app.component.ts

    constructor(platform: Platform){
     platform.ready().then(()=>{
       platform.registerBackButtonAction(()=>this.myHandlerFunction());
})


  myHandlerFunction(){
    //create alert
     }
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
4

This is my resolved and working Code. Thank you everyone.

constructor(platform: Platform,public alertCtrl: AlertController,public toastCtrl:ToastController) {
    platform.ready().then(()=>{
       platform.registerBackButtonAction(()=>this.myHandlerFunction());
       StatusBar.styleDefault();
      Splashscreen.hide();
})
  }

    myHandlerFunction(){
     let toast = this.toastCtrl.create({
      message: "Press Again to Confirm Exit",
      duration: 3000
    });
    toast.present(); 
     }
1

Html:

<button (click)="exitApp()">Close application<button>

TypeScript:

import {Platform} from 'ionic-angular';

@Page({ /*...*/ })
export MyPage {
 constructor(platform: Platform) {
  this.platform = platform;
 }
 exitApp(){
  this.platform.exitApp();
 }
}
1

Kinda late to the party... But there is more to back button other than closing the pushed pages, specially for project with several tab pages.

Sometimes a page is pushed NOT into the root page, but in one of the tab page's navCtrl. So we have to check for all of them.

Also, if no page or menu is open, we should circle around the most recently used tabs (similar to Instagram app) and go back to the previous tab. Moreover, we should not go back to each tab more than once (similar to Instagram)

I got inspired by the answers here and created a comprehensive method that handles all necessary features:

  • Side menu: Closes the side menu if it was open
  • Pushed pages: Closes any pages that might have been pushed on any of the tab pages’ nav controller
  • Switch between tabs: If the menu was closed, and there was no pushed page, it should take the user back to the previous recently used tab using a stack.
  • Show alert: If there was no previous recently used tab, an alert box should ask the user if they want to exit.

The details are in this blog post

A demo code can be downloaded from my github.

Ari
  • 7,251
  • 11
  • 40
  • 70
1

I managed to create this function by doing a lot of research. Hope it helps.

    // I am using this.isExitAlertOpen just to make sure that the alert does not open if already open.

    handleBackButton() {
    this.platform.registerBackButtonAction(() => {
        // const activePortal =
        // this.ionicApp._modalPortal.getActive() ||
        // this.ionicApp._loadingPortal.getActive() ||
        // this.ionicApp._toastPortal.getActive() ||
        // this.ionicApp._overlayPortal.getActive();

        // console.warn('ACTIVE PORTALS', activePortal);

        const activeModal = this.ionicApp._modalPortal.getActive();
        console.warn('MODAL', activeModal);

activePortal can be used to find the relevant active portals which includes alert, loader, modal, etc. If you want to handle everything with the back button or some of them uncomment according to your usage

In my case I only wanted to check if modal was active so I checked only for modal.

        //  if (activePortal) {
        //    activePortal.dismiss();
        //  }

        if (activeModal) {
            activeModal.dismiss();
        } else if (this.nav.canGoBack()) {
            this.nav.pop();
        } else {
            if (this.isExitAlertOpen) return;
            this.isExitAlertOpen = true;
            this.showExitAlert();
        }
    });
}

showExitAlert() {
    this.alertCtrl.create({
        title: 'Exit',
        message: 'Are you sure you want to exit the app?',
        enableBackdropDismiss: false,
        buttons: [
            {
                text: 'Yes',
                handler: () => {
                    this.isExitAlertOpen = false;
                    this.platform.exitApp();
                }
            }, {
                text: 'Cancel',
                role: 'cancel',
                handler: () => {
                    this.isExitAlertOpen = false;
                }
            }
        ]
    }).present();
}
d_bhatnagar
  • 1,419
  • 1
  • 12
  • 20