How do you show an alert
, that the user must close, before going back to the previous page? I'm using the standard <ion-navbar *navbar>
arrow button.
I tried hooking into the NavController
event ionViewWillLeave
like this, but it doesn't work:
ionViewWillLeave() {
let alert = Alert.create({
title: 'Bye',
subTitle: 'Now leaving',
buttons: ['OK']
});
this.nav.present(alert);
}
This shows the alert, but doesn't go back once it is closed. If I comment it out, the back button works fine.
The accepted solution doesn't work in RC3, here's a new one using Nav Controller's Nav Guard:
ionViewCanLeave(): Promise<void> {
return new Promise((resolve, reject) => {
let confirm = this.alertCtrl.create({
title: 'Are you sure?',
message: 'Bunnies will die :(',
buttons: [{
text: 'OK',
handler: () => {
resolve();
},
}, {
text: 'Cancel',
handler: () => {
reject();
}
}],
});
confirm.present();
})
}
If you are navigating using push() on the nav controller, you also need to do a catch on it otherwise it will throw an unhandled error:
this.navCtrl.push(SomePage).catch(() => {});
UPDATE
As of Ionic2 RC, now we can use Nav Guards.
In some cases, a developer should be able to control views leaving and entering. To allow for this, NavController has the ionViewCanEnter and ionViewCanLeave methods. Similar to Angular 2 route guards, but are more integrated with NavController
So now we can do something like this:
someMethod(): void {
// ...
this.showAlertMessage = true;
}
ionViewCanLeave() {
if(this.showAlertMessage) {
let alertPopup = this.alertCtrl.create({
title: 'Exit',
message: '¿Are you sure?',
buttons: [{
text: 'Exit',
handler: () => {
alertPopup.dismiss().then(() => {
this.exitPage();
});
}
},
{
text: 'Stay',
handler: () => {
// need to do something if the user stays?
}
}]
});
// Show the alert
alertPopup.present();
// Return false to avoid the page to be popped up
return false;
}
}
private exitPage() {
this.showAlertMessage = false;
this.navCtrl.pop();
}
I prefer to use the this.showAlertMessage
property, so we can have more control over when we need to show the alert if the user tries to exit the page. For instance, we may have a form in the page, and if the user didn't make any changes, we don't want to show the alert (this.showAlertMessage = false
) and if the form was actually changed, we want to show the warning (this.showAlertMessage = true
)
OLD ANSWER
After a few hours struggling with this, I've found the solution.
One issue that I had to face is that the ionViewWillLeave
is executed also when the alert
is closed so that makes things more complicated (when the view
is about to be closed because you pressed the back button, the alert
shows up, but when you click ok, that fires the event again and opens the alert
again and so on...).
Another thing to keep in mind is that ActionSheets
and Alerts
get added to the navigation stack
, so this.nav.pop()
instead of removing the current view from the stack, removes the alert
(and because of that we may feel it's not working properly).
That being said, the solution I've found is:
import {Component} from '@angular/core';
import {NavController, NavParams, Alert} from 'ionic-angular';
@Component({
templateUrl: 'build/pages/mypage/mypage.html',
})
export class MyPage{
// ....
confirmedExit: boolean = false;
constructor(private nav: NavController, navParams: NavParams) {
// ...
}
ionViewWillLeave() {
if(!this.confirmedExit) {
let confirm = Alert.create({
title: 'Bye',
message: 'Now leaving',
buttons: [
{
text: 'Ok',
handler: () => {
this.exitPage();
}
}
]
});
this.nav.present(confirm);
}
}
public exitPage(){
this.confirmedExit = true;
this.nav.remove().then(() => {
this.nav.pop();
});
}
}
So:
confirmedExit
variable to know if you already clicked the ok button (so you confirmed you wanted to exit the page, and with that I know that the next time the ionViewWillLeave
event is fired, I don't have to show the alert
)exitPage
method, first I do this.nav.remove()
to remove the alert
from the stack, and once that's done, we do the this.nav.pop()
to go back to the previous page.this is my version of Bostjan answer, without throwing unhandled exception.
ionViewCanLeave(): Promise<boolean> {
return new Promise(resolve => {
if (!this.formGroup.dirty) return resolve(true);
this._alertCtrl.create({
title: 'Confirm leaving',
message: 'There is unsave work, do you like to continue leaving?',
buttons: [{
text: 'Leave',
handler: () => {
resolve(true);
}
}, {
text: 'Stay',
handler: () => {
resolve(false);
}
}]
}).present();
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With