Ionic 4 stacked navigation and android hardware back button

Hello,

Just recently migrated to Ionic 4, using the sidemenu template.
As this is for a hybrid app, I am relying on the stack style navigation as per v3.

The issue I am seeing is if I use the hardware back button to navigate, it goes through the entire navigation history, as it is now using angular-router. It should just go back to the root page.

I need the functionality available in v3 to be maintained, as navigating back through the entire history isn’t suitable for hybrid apps, in my opinion.

app.component.html

Menu {{p.title}}  Settings  Logout

import { Component } from ‘@angular/core’;

import { Platform, NavController, } from ‘@ionic/angular’;
import { SplashScreen } from ‘@ionic-native/splash-screen/ngx’;
import { StatusBar } from ‘@ionic-native/status-bar/ngx’;
import { interval } from ‘rxjs’;
import { Router } from ‘@angular/router’;

@Component({
selector: ‘app-root’,
templateUrl: ‘app.component.html’//,
})

export class AppComponent {

public appPages = [
{
title: ‘All Animals’,
url: ‘/animal-list’
},
{
title: ‘BEEP’,
url: ‘/beep/home’
},
{
title: ‘Pending’,
url: ‘/pending’
}
];

isActive: boolean = true;

constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
public nav: NavController,
public router: Router
) {
this.initializeApp();
}

initializeApp() {
this.platform.ready().then(() => {

  this.statusBar.styleDefault();
  this.splashScreen.hide();
  console.log("Initialising App");
  this.nav.navigateRoot('/');

});

}

logout() {

this.nav.navigateRoot('/login/1');

}

settings() {

this.nav.navigateRoot('/settings');

}

navigate(route) {
// this.nav.navigateRoot(route);
// this.router.navigate([route], {replaceUrl:true});
this.router.navigate([route]);
// this.location.replaceState(route);
}

}

Ionic:

Ionic CLI : 5.2.4 (C:\Users\craig\AppData\Roaming\npm\node_modules\ionic)
Ionic Framework : @ionic/angular 4.6.2
@angular-devkit/build-angular : 0.13.9
@angular-devkit/schematics : 7.3.9
@angular/cli : 7.3.9
@ionic/angular-toolkit : 1.5.1

Cordova:

Cordova CLI : 8.1.2 (cordova-lib@8.1.1)
Cordova Platforms : android 7.1.4
Cordova Plugins : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 4.1.1, (and 9 other plugins)

Utility:

cordova-res : 0.3.0 (update available: 0.6.0)
native-run : 0.2.6 (update available: 0.2.8)

System:

NodeJS : v8.11.1 (C:\Program Files\nodejs\node.exe)
npm : 6.4.1
OS : Windows 10

you could try setting this in your app.component

this.platform.backButton.subscribeWithPriority(() => { // Navigate wherever you want here })

Thanks @christhompson05 for the code.
I can’t seem to get that to trigger any sort of event though with backbutton.subscribe or backbutton.subscribeWithPriority. I think there may be a known bug with the latter function.

I am making some progress with an event listener:

if (this.platform.is(‘android’)) {
// this.platform.backButton.subscribe( () => {
// console.log(“back button pressed”);
// })

    let rootPages = this.appPages.slice();

    //this is an extra 'root' page, that is not part of the main navigation
    rootPages.push(
      { title: 'Settings', url: '/settings' },
      { title: 'Home', url: '/home' }
    );

    document.addEventListener("backbutton", () => {

      //If this is my login page, and the user presses back, close the app
      if (this.router.url.indexOf('/login') >= 0) {
        navigator['app'].exitApp();
      }

      //if this page is one of my 'root' pages, and the user presses back, give them the logout option.
      let isRoot: boolean = false;

      rootPages.forEach((page) => {
        if (page.url === this.router.url) {
          console.log("Is a root page");
          isRoot = true;
        }
      });

      if (isRoot) {
        this.presentLogoutConfirm();
      } else {
        // use the NavController library to handle the pop()
        this.nav.pop()
          .then(() => {
            console.log("popping url", this.router.url);
          });
      }

    }, false);