Ionic hardware back button nightmare

Alexander Mitrev
3 min readJan 13, 2019

--

Just as a precondition I should say that I’m an Ionic newbie, so my approach might not be the smartest one or even not the cleanest one but it worked for me so I decided to share with you my experience.

Currently I’m working on a new Ionic project for which we decided to use the not officially released version of Ionic — 4.0.0-rc.0. Like most of the mobile applications today we wanted ours to have both software and of course the hardware buttons for going back. Of course initially I tried with the provided by the framework ion-back-button but when the user combined the software and the hardware buttons the behaviour of the program was ridiculous — it was jumping around from view to view. I tried almost every approach that someone gave in internet(like this) but with no success. There was always something that didn’t work well. The problem seems to be that Ionic doesn’t handle the same way the two buttons actions. So the decision taken for my approach was clear — make the two buttons work the same way.

To achieve this I created a custom navigation service which contains my navigation function:

public navigateToPreviousPage() {  const url = this.router.url;  if (url.match("(^\/[a-zA-Z0-9\-\.]*)$")) {    navigator['app'].exitApp();  } else {    this.navController.navigateBack(url.replace(new RegExp("(\/([a-zA-Z0-9\-\.])*)$"), ""));  }}

I was initially using the IonRouterOutlet to move back as suggested in the Ionic forum but for me this approach didn’t worked well. You can give it a chance it if you want:

this.routerOutlets.forEach((outlet: IonRouterOutlet) => {  if (outlet && outlet.canGoBack()) {    outlet.pop();  }});

The second thing I created was a custom back button component which calls the previously created navigation service. I used mine component instead of ion-back-button. This way we can prevent ourselves from a side behavior of the Ionic one.

<ion-button (click)=”goBack()”>  <ion-icon slot=”icon-only” name=”arrow-back”></ion-icon></ion-button>goBack() {  this.navigationService.navigateToPreviousPage();}

And now is time for the tricky part — the way I subscribe for the hardware back button click event. If the standard Platform.backButton.subscribe() method is used here its default behaviour will propagate the back click event after the subscription code is executed and this leads to the strange behaviour described at the beginning of this article. But in Ionic 4 there is another method called subscribeWithPriority() which stops the propagation of the event after its execution and if we subscribe with high priority and execute our prefered navigation instead of default one then it is going to work as we want. So inside my AppComponent I call the following function

hardwareBackButton() {  // subscribeWithPriority(“@ionic/angular”: “4.0.0-rc.0”) fixes the strange behavior when combining software & hardware back buttons. Its current behaviour may vary with the consecutive versions.  this.platform.backButton.subscribeWithPriority(1, () => {    this.navigationService.navigateToPreviousPage();  });}

This way I have the required routing with no side effect when using software and hardware back buttons.

--

--