I have a Modal in Ionic 4. I\'d like to close it, when a user press the back button on her mobile (or the bac
Based on the initial answer by Markus, You can decide to; Instead of unsubscribing after each back button event. You may want to listen to back-button events globally in your application and only call exit on specific pages.
import { fromEvent } from "rxjs"; // import fromEvent from rxjs
import { Router } from "@angular/router"; // import angular router as well
import { Location } from "@angular/common"; // import location from angular common
constructor(private router: Router, private location: Location) {
// Call the function when the app initializes at app.component.ts. it will watch for // back button events globally in the application.
this.backButtonEvent();
}
// Function to present the exit alert
async exitAlert() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: "Are you sure you want to exit the app?",
buttons: [
{
text: "Cancel",
role: "cancel",
cssClass: "secondary",
handler: blah => {}
},
{
text: "Close App",
handler: () => {
navigator["app"].exitApp();
}
}
]
});
await alert.present();
}
// function to subscribe to the backbutton event
backButtonEvent(): void {
const event = fromEvent(document, "backbutton");
event.subscribe(async () => {
// When the current route matches a specific page/route in the app where u
// want to exit on back button press.
// else assume the user wants to navigate to a previous page
if(this.router.url === "<example page-url to exit from>") { this.exitAlert()
}
else { this.location.back() }
});
}
Update, for Ionic 5 (Angular)
in your-modal.page.ts
import { ModalController } from '@ionic/angular';
at the top of your modal's .ts file. Then in your constructor you can just denote a -public- relationship to the controller, that way it's accessible by your view.
also in your-modal.page.ts
constructor(
public modalCtrl: ModalController
) {}
Now you can inline the close command:
in your-modal.page.html
<ion-header color="dark">
<ion-toolbar color="dark">
<ion-title>Modal Title</ion-title>
<ion-buttons slot="primary">
<ion-button (click)="modalCtrl.dismiss()">
<ion-icon slot="icon-only" name="close"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
Slot "primary" makes the buttons move to the right in iOS.
Enol's answer helped me find a solution, thanks for that.
platform.registerBackButtonAction
does no longer exist in v4. I tried platform.backButton.subscribe
instead, but it didn't work. What works is this:
private backbuttonSubscription: Subscription;
constructor(private modalCtrl: ModalController) {
ngOnInit() {
const event = fromEvent(document, 'backbutton');
this.backbuttonSubscription = event.subscribe(async () => {
const modal = await this.modalCtrl.getTop();
if (modal) {
modal.dismiss();
}
});
}
ngOnDestroy() {
this.backbuttonSubscription.unsubscribe();
}
For ionic 5 user
this.platform.backButton.subscribeWithPriority(999, async() => {
if (this.modalCtrl.getTop()) {
const modal = await this.modalCtrl.getTop();
console.log(modal)
if (modal) {
this.modalCtrl.dismiss();
return;
} else {
if (this.router.url=="/myrootpage" ) {
navigator['app'].exitApp();
} else {
this.navCtrl.pop();
}
}
} else {
if (this.router.url=="/myrootpage") {
navigator['app'].exitApp();
} else {
this.navCtrl.pop();
}
}
});
You can use the registerBackButtonAction
method that Platform service contains. This method allows override the default native action of the hardware back button. The method accepts a callback function as parameter where you can implement your logic. In summary you should do the following:
registerBackButtonAction
in the ngOnInit (or another init method) and pass a function callback as parameter that executes the logic to close the modal (this.modalController.dismiss();
)registerBackButtonAction
returns a function that when is called the action is removed.The code should be something like:
constructor(private platform: Platform) {
...
}
ngOnInit() {
this.unregisterBackAction = this.platform.registerBackButtonAction(() => {
this.modalController.dismiss();
})
}
ngOnDestroy() {
if(this.unregisterBackAction) this.unregisterBackAction();
}
Yes, are almost on the way.... you just need to change in HTML part. I did in this way.
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button color="dark" (click)="closeModal()">
<ion-icon name="arrow-back"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title>Create Pin</ion-title>
</ion-toolbar>
</ion-header>
after this, you just need to create a function that will close your modal popup. in your ts file
closeModal() {
this.modalCtrl.dismiss();
}
I hope that will help you.