[Fixed] Ionic 4: show a spinner until the data is retrieved

Issue

I used the “Ionic Loading Controller” to show a spinner until the data is retrieved then it calls “dismiss()” to dismiss it.
it works fine, but sometimes when the app already has the data, the “dismiss()” is called before the “create()” and “present()” is done which will keep the spinner without dismissing…

I tried to call the data inside “loadingController.present().then()”, but that caused the data to be slower…

is this a bug?
how to solve this issue?

Example of my code:

customer: any;

constructor(public loadingController: LoadingController, private customerService: CustomerService)

ngOnInit() {
  this.presentLoading().then(a => consloe.log('presented'));
  this.customerService.getCustomer('1')
  .subscribe(customer => {
    this.customer = customer;
    this.loadingController.dismiss().then(a => console.log('dismissed'));
  }
}

async presentLoading() {
  const loading = await this.loadingController.create({
    message: 'wait. . .',
    duration: 5000
  });
  return await loading.present();
}

Solution

this is how I solved my issue.

I used a boolean variable “isLoading” to change to false when dismiss() is called.
after present() is finished if “isLoading” === false (means dismiss() already called) then it will dismiss immediately.

also, I wrote the code in service so I don’t have to write it again on each page.

loading.service.ts

import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';

@Injectable({
  providedIn: 'root'
})
export class LoadingService {

  isLoading = false;

  constructor(public loadingController: LoadingController) { }

  async present() {
    this.isLoading = true;
    return await this.loadingController.create({
      // duration: 5000,
    }).then(a => {
      a.present().then(() => {
        console.log('presented');
        if (!this.isLoading) {
          a.dismiss().then(() => console.log('abort presenting'));
        }
      });
    });
  }

  async dismiss() {
    this.isLoading = false;
    return await this.loadingController.dismiss().then(() => console.log('dismissed'));
  }
}

then just call present() and dismiss() from the page.

the example in question:

customer: any;

constructor(public loading: LoadingService, private customerService: CustomerService)

ngOnInit() {
  this.loading.present();
  this.customerService.getCustomer('1')
  .subscribe(
    customer => {
      this.customer = customer;
      this.loading.dismiss();
    },
    error => {
      console.log(error);
      this.loading.dismiss();
    }
  );

Leave a Reply

(*) Required, Your email will not be published