8
votes

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
Seems like you need to return the promise. Essentially return confirm.present(); instead of false.Aluan Haddad

2 Answers

0
votes

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.

-1
votes

You don't need a promise for this, you just need to return true or false if the user is able to leave the page, so if he wants to leave and confirm this in the alert you set your allowedToLeave to true and pop your page, it'll call ionViewCanLeave again but this time it'll not enter your if statement.

  // About to leave
  ionViewCanLeave() {
    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.navCtrl.pop();
          },
        }, {
          text: 'Cancel',
          role: 'cancel'
        }],
      });
      confirm.present();
    };
    return true;
  }

Hope this helps.