Handling hardware back button in Ionic3 Vs Ionic4
Please find the below code for the Android hardware back button action in ionic3
. As Ionic4
uses angular routing for navigation how the pop event will take place for the back button? If we want to pop to the last page we can use the following code this.navCtrl.goBack('/products');
.
But how we can use it for the android hardware back button action in ionic4
?
Ionic3 hardware back button action
this.platform.registerBackButtonAction(() => {
let activePortal = this.ionicApp._loadingPortal.getActive() ||
this.ionicApp._modalPortal.getActive() ||
this.ionicApp._toastPortal.getActive() ||
this.ionicApp._overlayPortal.getActive();
if (activePortal) {
activePortal.dismiss();
} else {
if (this.nav.canGoBack()) {
***this.nav.pop();***
} else {
if (this.nav.getActive().name === 'LoginPage') {
this.platform.exitApp();
} else {
this.generic.showAlert("Exit", "Do you want to exit the app?", this.onYesHandler, this.onNoHandler, "backPress");
}
}
}
});
Solution 1:
Update: This was fixed in v4.0.0-beta.8 (dfac9dc)
Related: ionic4 replacement for registerBackButtonAction
This is tracked on GitHub, in the Iconic Forum and Twitter
Until there is an official fix, you can use the workaround below.
Using platform.backButton.subscribe
(see here)platform.backButton.subscribeWithPriority(0, ...)
to let ionic handle closing all the modals/alerts/... , the code ionic uses when its own back button is pressed and the new router-controller together we get something like this:
import { ViewChild } from '@angular/core';
import { IonRouterOutlet, Platform } from '@ionic/angular';
import { Router } from '@angular/router';
//...
/* get a reference to the used IonRouterOutlet
assuming this code is placed in the component
that hosts the main router outlet, probably app.components */
@ViewChild(IonRouterOutlet) routerOutlet: IonRouterOutlet;
constructor(
...
/* if this is inside a page that was loaded into the router outlet,
like the start screen of your app, you can get a reference to the
router outlet like this:
@Optional() private routerOutlet: IonRouterOutlet, */
private router: Router,
private platform: Platform
...
) {
this.platform.backButton.subscribeWithPriority(0, () => {
if (this.routerOutlet && this.routerOutlet.canGoBack()) {
this.routerOutlet.pop();
} else if (this.router.url === '/LoginPage') {
this.platform.exitApp();
// or if that doesn't work, try
navigator['app'].exitApp();
} else {
this.generic.showAlert("Exit", "Do you want to exit the app?", this.onYesHandler, this.onNoHandler, "backPress");
}
});
}
Solution 2:
Try This: app.comonent.ts
import { Component, ViewChildren, QueryList } from '@angular/core';
import { Platform, ModalController, ActionSheetController, PopoverController, IonRouterOutlet, MenuController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { Router } from '@angular/router';
import { Toast } from '@ionic-native/toast/ngx';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
// set up hardware back button event.
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
public modalCtrl: ModalController,
private menu: MenuController,
private actionSheetCtrl: ActionSheetController,
private popoverCtrl: PopoverController,
private router: Router,
private toast: Toast) {
// Initialize app
this.initializeApp();
// Initialize BackButton Eevent.
this.backButtonEvent();
}
// active hardware back button
backButtonEvent() {
this.platform.backButton.subscribe(async () => {
// close action sheet
try {
const element = await this.actionSheetCtrl.getTop();
if (element) {
element.dismiss();
return;
}
} catch (error) {
}
// close popover
try {
const element = await this.popoverCtrl.getTop();
if (element) {
element.dismiss();
return;
}
} catch (error) {
}
// close modal
try {
const element = await this.modalCtrl.getTop();
if (element) {
element.dismiss();
return;
}
} catch (error) {
console.log(error);
}
// close side menua
try {
const element = await this.menu.getOpen();
if (element) {
this.menu.close();
return;
}
} catch (error) {
}
this.routerOutlets.forEach((outlet: IonRouterOutlet) => {
if (outlet && outlet.canGoBack()) {
outlet.pop();
} else if (this.router.url === '/home') {
if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
// this.platform.exitApp(); // Exit from app
navigator['app'].exitApp(); // work in ionic 4
} else {
this.toast.show(
`Press back again to exit App.`,
'2000',
'center')
.subscribe(toast => {
// console.log(JSON.stringify(toast));
});
this.lastTimeBackPress = new Date().getTime();
}
}
});
});
}
}
it's work for me, in ionic v4 beta