How to wait for Ionic Alert to respond

Hi folks, This is one of that issue which is a very niche use case and hard to find the answer to. That’s why I felt like it’s worth sharing how I found my way around this problem 😊. In this post, we will see how we can wait for an Alert to respond back and then act on it.

In this post I am using Angular as I mostly use it in my projects, but I think it should serve the purpose for everyone’s understanding. So let’s get started.

General usage of Alert component in Ionic

  async presentAlertConfirm() {
    const alert = await this.alertController.create({
      header: 'Confirm!',
      message: 'Message <strong>text</strong>!!!',
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel',
          cssClass: 'secondary',
          handler: (blah) => {
            console.log('Confirm Cancel: blah');
          }
        }, {
          text: 'Okay',
          handler: () => {
            console.log('Confirm Okay');
          }
        }
      ]
    });

    await alert.present();
  }

You can find more at Alert Ionic Documentation.

Code snippet that you are seeing above is from official documentation and it’s pretty straight forward. To explain it in brief, when you call above function an Alert component will show up with provided message and two buttons. “Cancel” button closes the Alert and performs function assigned to handler and “Okay” button performs only the function assigned to it.

Use case

Consider a scenario, where you have two services Service A and Service B. In Service B above method is implemented with slight modification. And in Service A you have function Let’s say deleteAccountPermanently().

Now you want to achieve the workflow like,

  1. Show user the Alert.
  2. If user clicks on “Cancel”, cancel the workflow.
  3. If user clicks on “Okay”, perform this function deleteAccountPermanently().

But the problem is 😥

I can’t write my function like this,

  async deleteAccountPermanently() {
      try {
        await this.utilService
          .presentAlert(
            'Delete all completed todos',
            'Do you really want to delete all completed todos?',
            'Cancel',
            'Yes, delete!',
            this,
            this.deleteAllCompletedTodosActual
        );
        await this.utilService.presentToast('Deleted successfully', '', 500, 'success');
      } catch (error) {
        await this.utilService.dismissLoading();
        await this.utilService.presentToast('Oops', error.message, 1000, 'danger');
      }
  }

First Attempt 😭

Because it will not wait, till user clicks on “Cancel” or “Yes, delete!”. On top of that, we want to terminate the whole workflow when user clicks “Cancel”.

How to wait for the Alert 🤔

Simple!! Instead, Pass this function to this Alert Component Service, but how?

Let’s modify our function and the Alert Service a bit.

Modified Alert function:

async presentAlert(
    header: string,
    message: string,
    cancelButtonName: string,
    confirmButtonName: string,
    context: object,
    confirmAction: () => {}
  ) {
    const alert = await this.alertController.create({
      header,
      message,
      buttons: [
        {
          text: cancelButtonName,
          role: 'cancel'
        }, {
          text: confirmButtonName,
          handler: confirmAction.bind(context)
        }
      ]
    });

    await alert.present();
  }

Updated PresentAlert() function in Service B

Modified deleteAccountPermanently() function

  async deleteAccountPermanently() {
      await this.utilService
        .presentAlert(
          'Delete all completed todos',
          'Do you really want to delete all completed todos?',
          'Cancel',
          'Okay',
          this,
          this.deleteAccountPermanentlyActual
      );
  }

  async deleteAccountPermanentlyActual() {
    try {
      await this.firebaseDbService.deleteAccountPermanently();
      await this.utilService.presentToast('Deleted successfully', '', 500, 'success');
    } catch (error) {
      await this.utilService.presentToast('Oops', error.message, 1000, 'danger');
    }
  }

Extracting deleteAccountPermanently() function in two functions 😎

And, problem solved 🎉

So what we just did in above steps is,

  1. Extract deleteAccountPermanently() functions business logic in another method as you can see above.
  2. And we are using deleteAccountPermanently(), only to show Alert to user.
  3. Now if you noticed the changes in presentAlert() function, you will see that we have added two more parameters to it.
    1. context – which is the execution context, in it will be of Service A.
    2. confirmAction – which is the reference to the function that we need to run inside provided context.
  4. And we are assigning the handler of “Okay” button with confirmAction function in context by binding them. So when user clicks on “Okay” it will execute it as it was running inside Service A.
  5. Back to Service A, we are passing this(Execution Context of Service A) as context and newly extracted function as confirmAction.

And what means, is now it will only execute the delete operation when user clicks on “Okay” Or will terminate the workflow otherwise. Problem Solved 🎉.

To check out my other posts, click here.

I hope this solved your problem, peace ❤.

Spread the knowledge
Indrajeet Nikam
Indrajeet Nikam

I am tech enthusiast with love for web development ❤

Articles: 15