I used "Ionic Loading Controller" to show a spinner until the data is retrieved then it calls "dismiss()" to dismissed it. it works fine, but sometimes when the app already have 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 the 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(); }
I used "Ionic Loading Controller" to show a spinner until the data is retrieved then it calls "dismiss()" to dismissed it. it works fine, but sometimes when the app already have the data, the "dismiss()" is called before the "create()" and "present()" is done which will keep the spinner without dismissing...
const loading = await this. loadingController. create({ message: '<ion-img src="/assets/svg/shopping. svg" alt="loading..."></ion-img>', cssClass: 'scale-down-center', translucent: true, showBackdrop: false, spinner: null, duration: 2000 });
The ion-loading controller is a fabulous overlay that refrains the user’s interaction while current requests are being processed. The loading indicator in Ionic comes on top of the application’s content and can be removed or dismissed to continue the user interaction with the app. Open terminal, type and then execute command to install Ionic CLI:
The loading indicator can be dismissed automatically after a specific amount of time by passing the number of milliseconds to display it in the duration of the loading options. To dismiss the loading indicator after creation, call the dismiss () method on the loading instance.
The spinner name should be passed in the spinner property. If a value is not passed to spinner the loading indicator will use the spinner specified by the platform. The loading indicator can be dismissed automatically after a specific amount of time by passing the number of milliseconds to display it in the duration of the loading options.
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 a service so I don't have to write it again in 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(); } );
Here's how I've solved the same issue in my project. I use this service in the HTTP Interceptor to show the loader for all the REST API calls inside my app.
loading.service.ts
import {Injectable} from '@angular/core'; import {LoadingController} from '@ionic/angular'; @Injectable({ providedIn: 'root' }) export class LoadingService { constructor(public loadingController: LoadingController) { } async present(options: object) { // Dismiss all pending loaders before creating the new one await this.dismiss(); await this.loadingController .create(options) .then(res => { res.present(); }); } /** * Dismiss all the pending loaders, if any */ async dismiss() { while (await this.loadingController.getTop() !== undefined) { await this.loadingController.dismiss(); } } }
In the original question context this could be used like below:
... import {LoadingService} from '/path/to/loading.service'; ... customer: any; constructor(public loadingService: LoadingService, private customerService: CustomerService) ngOnInit() { this.loadingService.present({ message: 'wait. . .', duration: 5000 }); this.customerService.getCustomer('1') .subscribe(customer => { this.customer = customer; this.loadingService.dismiss(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With