I'm still rather new to Ionic 4. I'm making an App that receives push notification. The navigation inside the app works like this:
Home page -> Detail page
Every time the user taps on the notification, the app will open and navigates to Detail page. The navigation works but since the navigation history is empty, if the user taps on the hardware back button, the app exits. I want it to redirect the user to Home page instead.
How do I achieve this in Ionic 4? is there any way to push a page to navigation history? I have read the documentation but couldn't find anything about this. The closest was probably NavCtrl.push()
but it's no longer usable in Ionic 4.
Thank you.
There may be an easier way to do this but the following approach is a very flexible one because it'd allow you to run any custom logic when the user wants to go back from the page shown after a push notification or a deep link is opened.
Please take a look at this StackBlitz demo.
Please notice that in the demo, I'm redirecting to the DetailsPage
as soon as the app is loaded because of the following code from the app-routing.module
file:
{
path: "",
redirectTo: "/details/1?fromDeepLink=true", // <-- here!
pathMatch: "full"
}
Anyway, the important part happens in the DetailsPage
. There, you need to handle what happens when the user tries to go back using a) the back button from the header and b) the physical back button from Android devices
The code is pretty self-explanatory, but basically in that page I'm looking for the fromDeepLink
query string param, and if it's true
, the app will register a custom action for both the back button from the header and for the physical back button from Android devices.
The custom action sets the HomePage
as the root page, but sets the animationDirection
parameter to be 'back'
. That way it'd look like the user is going back to that page even if we're actually adding it to the navigation stack.
It's important to notice that this custom handler is being removed as soon as the user leaves the page so that we don't affect the default behaviour of the back button in any other pages.
import { Component, OnInit, ViewChild } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { IonBackButtonDelegate, NavController, Platform, ViewDidEnter, ViewWillLeave } from "@ionic/angular";
import { Subscription } from "rxjs";
@Component({
selector: "app-details",
templateUrl: "./details.page.html",
styleUrls: ["./details.page.scss"]
})
export class DetailsPage implements OnInit, ViewDidEnter, ViewWillLeave {
@ViewChild(IonBackButtonDelegate, { static: false })
public backButton: IonBackButtonDelegate;
public itemId: number;
public fromDeepLink: boolean = false;
private unregisterBackButtonAction: Subscription;
constructor(
private platform: Platform,
private route: ActivatedRoute,
private navCtrl: NavController,
) {}
ngOnInit() {
const itemIdParam = this.route.snapshot.paramMap.get("itemId");
const fromDeepLinkParam = this.route.snapshot.queryParamMap.get('fromDeepLink');
this.itemId = +itemIdParam;
this.fromDeepLink = fromDeepLinkParam
? fromDeepLinkParam.toLocaleLowerCase() === 'true'
: false;
}
ionViewDidEnter() {
if(this.fromDeepLink) {
this.initializeCustomBackButtonAction()
}
}
ionViewWillLeave() {
if(this.fromDeepLink) {
this.removeCustomBackButtonAction();
}
}
private initializeCustomBackButtonAction(): void {
const leavingCallback = () => {
console.log('Using custom back button action');
this.navCtrl.navigateRoot('/home', { animationDirection: 'back' });
};
// Override the back button from the header
if (this.backButton) {
this.backButton.onClick = leavingCallback;
}
// Override the physical back button from Android devices
this.unregisterBackButtonAction = this.platform.backButton.subscribeWithPriority(10, leavingCallback);
}
private removeCustomBackButtonAction(): void {
this.unregisterBackButtonAction?.unsubscribe();
}
}
Please also notice that by default the ion-back-button
is not shown if there's no page before the current page in the navigation stack, so in the demo I'm setting the defaultHref
property like this:
<ion-back-button defaultHref></ion-back-button>
I'm leaving it empty because the component is actually going to override what this back button does with my custom back button action. But the defaultHref
needs to be added to the template, otherwise the back button won't be shown.