2

In my app.component i'm trying to trigger the hardware back button like this: https://stackoverflow.com/a/52349119/4197536

The event is triggered fine but something doesn't work on outlet.canGoBack() cause it's always false.

Inside the backButton subscription i tried to console log the current outlet value and it always returns null.

Here the ViewChildren

@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;

Here the code

backButtonEvent() {
    this.platform.backButton.subscribeWithPriority(0, 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 menu
        try {
            const element = await this.menu.getOpen();
            if (element) {
                this.menu.close();
                return;
            }
        } catch (error) {
        }

      console.log('routerOutlets length', this.routerOutlets.length); // 1
      this.routerOutlets.forEach((outlet: IonRouterOutlet) => {
        console.log('outlet', outlet); // it's always null
      });
    });
  }

Here the app.component template

<ion-app>
  <ion-router-outlet></ion-router-outlet>
</ion-app>

Here my project info

Ionic:

   Ionic CLI                     : 5.2.0 (/usr/local/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.4.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

Capacitor:

   Capacitor CLI   : 1.1.1
   @capacitor/core : 1.1.1

Cordova:

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

Utility:

   cordova-res : not installed
   native-run  : 0.2.8 

System:

   NodeJS : v10.16.0 (/Users/enrico/.nvm/versions/node/v10.16.0/bin/node)
   npm    : 6.9.0
   OS     : macOS Mojave
   Xcode  : Xcode 10.2.1 Build version 10E1001
Rob
  • 14,746
  • 28
  • 47
  • 65

1 Answers1

0

This question is three years old now, but I encoutered the same problem with Ionic 6 and here's my answer.

This issue on Ionic's GitHub states that:

Injecting IonRouterOutlet requires that you inject it into a component inside of the ion-router-outlet element you want to have access to.

So if you add your logic in the app.component.ts you will end up with the IonRouterOutlet instance always undefined. I solved this by moving the logic inside my home.component.ts, the first one always loaded when running my app: a small caveat, when you programmatically subscribe to the back button events you override the default behavuiour, so you'll need to implement the standard "back" logic.

This is my home.component.ts:

import { Component, Optional } from '@angular/core';
import { App } from '@capacitor/app';
import { IonRouterOutlet, Platform } from '@ionic/angular';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  constructor(
    private platform: Platform,
    @Optional() private routerOutlet?: IonRouterOutlet
  ) {
    this.platform.backButton.subscribeWithPriority(1, () => {
      if (!this.routerOutlet?.canGoBack()) {
        App.exitApp();
      } else {
        this.routerOutlet?.pop();
      }
    });
  }
}
alessiopremoli
  • 188
  • 2
  • 7