Ionic: detect navigation direction in `ionViewCanLeave` lifecycle method


#1

I have three pages: let’s call them A, B and C.

A has a link to B, and B has a link to C.

A -> B -> C

B contains a form. If the form is not filled in correctly, I’d like to prevent the user going back to A. However, they should still be allowed to go to C.

I thought about using ionViewCanLeave to prevent the user from going back to A, as this should also handle the user pressing the ‘Back’ button on Android. But, I need them to always be allowed to go to C. So, am I able to detect if the user is going ‘back’ or ‘forward’ in this lifecycle method?


#2

I would probably go with a modal for page C. Would that fit in your UX?


#3

Thanks for the suggestion, but I don’t think that would solve my issue (preventing user going from B -> A if form is not filled in correctly).

It seems as though this feature will be added to rc.5.


#4

You’d still use ionViewCanLeave to prevent the user from going back B -> A, but presenting a modal from B -> C will still work. Presenting a modal isn’t the same as pushing a whole new page to the nav stack.

I use this for complicated forms where I need the extra functionality of a modal that I can’t get from a typical select, prompt, or what have you.


#5

I did a trick, that worked:

Create a new variable in your “B” page:

canShowChangesAlert: boolean = true;

Whenever user enter this page, resets variable to default true:

ionViewDidEnter(){
	this.canShowChangesAlert= true;
}

When user try to quit this page, check if hes navigating to one page that cannot show alert (that will resolve the promise):

ionViewCanLeave(): Promise<void> {
	return new Promise<void>((resolve, reject) => {
		if ( !this.canShowChangesAlert || !this.hasChanges )
			resolve();
		else
		{
			let confirm = this.alertCtrl.create({
				title: 'Descartar alterações?',
				message: 'Algumas alterações foram feitas, deseja realmente sair sem salvar?',
				buttons: [{
					text: 'Sim',
					handler: () => {
						resolve();
					},
				}, {
					text: 'Não',
					handler: () => {
						reject();
					}
				}],
			});
			confirm.present();
		}
	})
  }

In other page calls that you dont want to show the alert (like going to your “C” page):

addSection() {
	this.canShowChangesAlert = false;
	this.navCtrl.push('YourCPage');
}

Obs: “hasChanges” is a function that I created to check if I have changes in my main page (like your “B” page):

get hasChanges(): boolean {
	return this.newsProv.newsSaved != JSON.stringify(this.newsProv.news);
}

Hope that it can help you or other people.