Here is how I fixed the router looping problem on Ionic 4. I am aware and previously implemented the famous back button workaround in Ionic 3, but that won't work on Ionic 4 since it uses angular routing.
So I was looking for some way to get the currently active view instance. If I get the view instance, then I can call some backButtonAction
function defined on that page (similar to the Ionic 3 workaround).
Okay, enough chit-chat. here is the code:
app.component.ts
export class AppComponent {
@ViewChildren(IonRouterOutlet) routerOutlets:QueryList<IonRouterOutlet>;
constructor(
private alertCtrl:AlertController,
private modalCtrl:ModalController,
private actionSheetCtrl: ActionSheetController,
private menu:MenuController,
private platform: Platform
){
this.initializeApp();
}
initializeApp(){
...
this.registerHardwareBackButton();
}
registerHardwareBackButton() {
this.platform.backButton.subscribe((e) => {
e.register(999, async () => {
// first close any alets, modal etc.
const actionsheet = await this.actionSheetCtrl.getTop();
if(actionsheet){
actionsheet.dismiss();
return;
}
const modal = await this.modalCtrl.getTop();
if(modal){
modal.dismiss();
return;
}
const alert = await this.alertCtrl.getTop();
if(alert){
alert.dismiss();
return;
}
const menu = await this.menu.getOpen();
if(menu){
menu.close();
return;
}
const outlet:any = this.routerOutlets.first();
const activeView = outlet.activated.instance; // the active view instance
//now calls the onBackButtonPress function in that instance
if(activeView.onBackButtonPress){
activeView.onBackButtonPress();
}else {
//some logic about what to do if onBackButtonPress is not defined, default action
}
});
});
}
and if you have a user navigation flow like this HomePage => Page1 => Page2
define onBackButtonPress
function on each like (just like the workaround for Ionic 3).
example:
on HomePage
onBackButtonPress(){
navigator['app'].exitApp(); //closes the app, bad UX
}
on Page1
onBackButtonPress(){
//back to previous page using location.back() or nav.pop()
this.location.back();
}