0
votes

I am working with ionic 5, and trying to use ion LoadingController with resolvers.

At first, the problem I had was that loadingController.dismiss() was called before loadingController.create() finished, so I followed the instructions here: Ionic 4: "Loading Controller" dismiss() is called before present() which will keep spinner without dismissing.

So, I created a Service to show and dismiss the loader like this:

  export class LoaderService {

  isLoading = false;

  constructor(public loadingController: LoadingController) { }

  async present() {
    this.isLoading = true;
    return await this.loadingController.create().then(a => {
      a.present().then(() => {
        if (!this.isLoading) {
          a.dismiss();
        }
      });
    });
  }

  async dismiss() {
    if (this.isLoading) {
      this.isLoading = false;
      return await this.loadingController.dismiss();
    }
    return null;
  }
}

And I call it in the app.component

 constructor(
    private platform: Platform, private loaderService: LoaderService,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private languageService: LanguageService,
    private appDataService: AppDataService,
    private popOverCtrl: PopoverController,
    private auth: AuthService, private router: Router
  ) {

      this.router.events.subscribe((event: Event) => {
        switch(true){
          case event instanceof NavigationStart: {
            this.loaderService.present();
            break;
          }

          case event instanceof NavigationEnd:
          case event instanceof NavigationCancel:
          case event instanceof NavigationError: {
            this.loaderService.dismiss();
            break;
          }
          default: {
            break;
          }
        }
      })
      this.initializeApp();
  }

But I am getting the following error:

enter image description here

4
Isn't your problem related to the fact that your service is call from the constructor ? as long as the app is not ready you cannot use safely Ionic components. - Ostn
I moved the service call to the ngInit of app.component and same result - alvardo
And in platform.ready ? - Ostn
Tried, and same result. - alvardo
@Ajt not really, I was forced to used a fixed Time out - alvardo

4 Answers

1
votes
import { Injectable } from '@angular/core';
import {
    HttpInterceptor,
    HttpRequest,
    HttpResponse,
    HttpHandler,
    HttpEvent,
    HttpErrorResponse
} from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { LoadingController } from '@ionic/angular';



@Injectable()
export class  SpinnerInterceptor implements HttpInterceptor {

  isLoading = false;
  loaderToShow: any;
  constructor(
    public loadingController: LoadingController
    ) { }
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      this.present();
      return next.handle(req).pipe(
                map((event: HttpEvent<any>) => {
                  this.dismiss();
                    if (event instanceof HttpResponse) {
                        console.log('event--->>>', event);
                    }
                    return event;
                }));
  }

  public loader:any
  async present() {
    this.loader = await this.loadingController.create({
      cssClass: 'my-custom-class',
      message: 'Please wait...',
      duration: 2000
    });
    await this.loader.present();
  }


    async dismiss() {
      let topLoader = await this.loadingController.getTop();
      while (topLoader) {
        if (!(await topLoader.dismiss())) {
          // throw new Error('Could not dismiss the topmost loader. Aborting...');
          break
        }
        topLoader = await this.loadingController.getTop();
      }
    }
}
0
votes

Uncaught (in promise): overlay does not exist is a very generic error and can appear in multiple situations. In general, it occurs when trying to resolve a promise and it does not exist.

The solution is quite simple, we are trying to close a modal or the loading component when it has not been created yet.

You should use the ionic lifecycle (see documentation) to be able to initialize the LoadingController before closing it:

  • ngOnInit
  • ionViewWillEnter
  • ionViewDidEnter
  • ionViewWillLeave
  • ionViewDidLeave
  • ngOnDestroy
ngOnInit() { // or you can use ionViewWillEnter()
    this.loaderService.present(); }

ionViewDidEnter() {
    this.loaderService.dismiss();
}

I hope it helps.

0
votes

Calling the loader in a timeout function solves it for me. All calls to the loader function are made from a shared service.

  presentLoading(duration?,text?) {
    this.platform.ready().then(()=>{
      setTimeout(()=>{
        this.startLoader(duration,text);
      },2000)
    })
  }
  async startLoader(duration?,text?){
    const loading = await this.loadingController.create({
      cssClass: 'my-custom-class',
      message: (text)?('Please wait...'+text):'Please wait...',
      duration: (duration)?duration:''
    });
    await loading.present();

    const { role, data } = await loading.onDidDismiss();
  }

and ensure you check if the loader is active before closing it

dismissLoader(){
    this.loadingController.getTop().then(v => v ? this.doStopLoader() : null);
  }
  doStopLoader(){
    this.loadingController.dismiss();
  }
 
0
votes

This can also be caused by running your app in the browser, particularly if using browser device emulation (Called "device toolbar" in Chrome and Responsive Mode in Firefox). Try disabling device toolbar (Ctrl+Shift+M) or running your app on a physical device or use a proper Emulator.