How to dismiss LoadingController once method is executed in Ionic Angular app?

I am creating a LoadingController below, presenting it, & executing some methods:

this.loadingCtrl.create({
      message: 'Sending Message...'
    }).then(loadingEl => {
      loadingEl.present();
      this.conversationsService.addMessageToConversation(this.conversation.id, this.form.value.message);
    });

The LoadingController should only be dismissed once addMessageToConversation() is successful.

Can someone please tell me how I can do this?

Here is addMessageToConversation() in case it is required:

addMessageToConversation(conversationId: string, message: string) {
    this._conversations.getValue().find(conversation => conversation.id === conversationId)
      .messages.push(
        new Message(
          Math.random().toString(),
          message,
          this.authService.userId,
          new Date(Date.now())
        ));
  }

Probably a good circumstance where an async function might work better. I generally find async functions work better when everything needs to execute in a specific order.

Depending on how the service works it’s also probably worth returning promises from your backend.

Consider this:

Conversation-detail.page.ts

async onSendMessage(): Promise<any> {
  try {
    const loader = await this.loadingCtrl.create({
      message: 'Sending Message...'
    });
    await loader.present();
    await this.conversationService.addMessageToConversation(this.conversation.id, this.form.value.message);
    loader.dismiss();
  } catch(e) {
    // Handle errors
  }
}

Conversations.service.ts

// As much as I'm a fan of code reusability maybe reconsider how many functions you're calling here.
// Unless you're using the functions repeatedly elsewhere it might not be worth breaking it up so much.

addMessageToConversation(conversationId: string, message: string): Promise<any> {
  return new Promise(async (resolve) => {
    await this.getConversationToAddMessage(conversationId).messages.push(this.createMessage(message));
    resolve();
  });
}

getConversationToAddMessage(id: string): Promise<any> {
  return new Promise((resolve) => {
    resolve(this._conversations.getValue().find(conversation => conversation.id === id));
  });
}

private createMessage(message: string): Message {
  return {
    id: Math.random().toString(),  // For truly unique IDs you should use some kind of timestamp based seed. Although random, random numbers can appear more than once.
    text: message,
    userId: this.authService.userId,
    timestamp: new Date(Date.now())
  }
}
1 Like

Thanks for your response. I’ve updated the code in my question above. Please take a look.

I would prefer if I could use some code like this:

this.loadingCtrl.create({
     message: 'Sending Message...'
   }).then(async loadingEl => {
     loadingEl.present();
     const res = await this.conversationsService.addMessageToConversation(this.conversation.id, this.form.value.message);
     this.loadMsg();
     this.form.reset();
     this.loadingCtrl.dismiss()
     
   });

But could I change addMessageToConversation() so that it returns a promise than I can use .then() on it?

You need to dismiss the instance of loadingCtrl existing in loadingEl so you would call

loadingEl.dimiss();

not

this.loadingCtrl.dimiss()

But could I change addMessageToConversation() so that it returns a promise than I can use .then() on it?

Yes but it’s an asynchronous functions anyway so I’m not sure why that would help you

I’m not 100% sure what I should be doing here

What I was trying to do was dismiss the loading controller once the message was successfully added