Ionic 4: "Loading Controller" dismiss() is called before present() which will keep spinner without dismissing
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(); }}
for Ionic 4 check this solution
Source Link
import { Component } from '@angular/core'; import { LoadingController } from '@ionic/angular'; @Component({ selector: 'app-home', templateUrl: 'home.page.html', styleUrls: ['home.page.scss'], }) export class HomePage { loaderToShow: any; constructor( public loadingController: LoadingController ) { } showAutoHideLoader() { this.loadingController.create({ message: 'This Loader Will Auto Hide in 2 Seconds', duration: 20000 }).then((res) => { res.present(); res.onDidDismiss().then((dis) => { console.log('Loading dismissed! after 2 Seconds'); }); }); } showLoader() { this.loaderToShow = this.loadingController.create({ message: 'This Loader will Not AutoHide' }).then((res) => { res.present(); res.onDidDismiss().then((dis) => { console.log('Loading dismissed! after 2 Seconds'); }); }); this.hideLoader(); } hideLoader() { setTimeout(() => { this.loadingController.dismiss(); }, 4000); } }