How can I use a nav guard on a tab change in Ionic?

Viewed 964

I am using Ionic 2. I have a view that the user should be prompted to confirm they want to leave when navigating away (a video is playing at the time, and it's probably an accidental navigation).

I have this working fine for when the user clicks the back button in top nav, or back hardware button (Android), using the following code:

  // About to leave
  ionViewCanLeave() {
    this.api.getDefaultMedia().pause();

    return new Promise((resolve, reject) => {
      if(!this.allowedToLeave) {
        let confirm = this.alertCtrl.create({
          title: 'Are you sure?',
          message: 'If you leave a class you will need to start over.  Are you sure you want to leave?  If you need a break you can pause by tapping the video.',
          buttons: [{
            text: 'OK',
            handler: () => {
              this.allowedToLeave = true;
              resolve();
            },
          }, {
            text: 'Cancel',
            handler: () => {
              reject();
            }
          }],
        });
        confirm.present();
      }
    });
  }

The view sits in a tab. Clicking a different tab does not call this function, so the user is not prompted, and the tab just switches.

How can I have this prompt shown on a tab change too? This view is not a root tab page.

--

I have tried using ionViewWillLeave(), which is called on a tab change, but it does not allow a way to prevent the user from switching. The below code does show the prompt, but after the tab has changed:

  // Called when user exits page via tab
  ionViewWillLeave() {
    this.api.getDefaultMedia().pause();

    if(!this.allowedToLeave) {
      let confirm = this.alertCtrl.create({
        title: 'Are you sure?',
        message: 'If you leave a class you will need to start over.  Are you sure you want to leave?  If you need a break you can pause by tapping the video.',
        buttons: [{
          text: 'OK',
          handler: () => {
            this.allowedToLeave = true;
            this.leave();
          },
        }, {
          text: 'Cancel',
          handler: () => {
            // Do nothing
          }
        }],
      });
      confirm.present();

      return false;
    }
  }

  // Leave the view
  leave() {
    this.navCtrl.pop();
  }
2 Answers

I have a simple one-liner solution for this because ionViewCanLeave is not available for Tabs. So, what you need to do is, throw a simple error from your ionViewWillLeave if you want to prevent the navigation :)

ionViewWillLeave() {
  if (!this.isValidForm()) {
    this.showPrompt();
    throw new Error('Form validation error!');
  }
}

This error will be caught by the View Controller of Ionic Framework on top of the tabs, which will stop the navigation.

Related