Ionic confirmation alert: await click on alert before continuing

Viewed 5751

I have a function that runs some arbitrary code, called calculate(). I have an if condition and if it is true I present an ionic confirm alert.

I can get the confirm alert to popup, however, I am trying to use async/await to wait for a response in the confirmation, but my understanding of async/await must be wrong. Here is basically what I am doing:

import { AlertController } from '@ionic/angular';

export class Calculator {
  private cancelResults:boolean = false;

  constructor(private alertController:AlertController) {}

  async calculate() {
    // If my condition is true.
    if (true) {
      // show the user a confirm alert.
      await this.warn();

      // break out of function since they hit cancel.
      if (this.cancelResults) return;
    }

    // The user hit Okay, continue with this function.
  }

  async warn() {
    const alert = await this.alertController.create({
      header: 'confirm',
      message: 'my message',
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel',
          handler: (blah) => {
            console.log('they hit cancel');
            this.cancelResults = true;
            return new Promise(resolve => setTimeout(resolve, 2000));
          }
        }, {
          text: 'Okay',
          handler: () => {
            console.log('they hit ok');
            return new Promise(resolve => setTimeout(resolve, 2000));
          }
        }
      ]
    });

    await alert.present();
  }
}

When the confirmation pops up, the remainder of the calculate() fn continues. I want it to wait for the confirmation response.

Any ideas of how to achieve this?

2 Answers

I figured it out! I needed to first set the await to a constant and then wrap the dialog in a promise rather than return an individual promise per response.

import { AlertController } from '@ionic/angular';

export class Calculator {
  constructor(private alertController:AlertController) {}

  async calculate() {
    // If my condition is true.
    if (true) {
      // show the user a confirm alert.
      const confirmation = await this.warn();
      // break out of function since they hit cancel.
      if (!confirmation) return;
    }

    // The user hit Okay, continue with this function.
  }

  async warn() {
    return new Promise(async (resolve) => {
      const confirm = await this.alertController.create({
        header: 'confirm',
        message: 'my message',
        buttons: [
          {
            text: 'Cancel',
            role: 'cancel',
            handler: () => {
              return resolve(false);
            },
          },
          {
            text: 'OK',
            handler: () => {
              return resolve(true);
            },
          },
        ],
      });

      await confirm.present();
    });
  }
}

I needed to figure this out recently also. For future readers, I think it is a bit simpler though to return the onDidDismiss() promise and check the role for whatever button was selected. Also, you can check for the 'backdrop' role in case they canceled by clicking the background.

const confirmation = await this.myAlert('Confirm', 'Message');

if (confirmation.role === 'cancel' || confirmation.role === 'backdrop') {
  // clean up code
  return;
}

myAlert(header: string, message: string) {
  return this.alertCtrl
    .create({
      header: header,
      message: message,
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel',
        },
        {
          text: 'Okay',
        },
      ],
    })
    .then((alertEl) => {
      alertEl.present();
      return alertEl.onDidDismiss();
    });
}
Related