2

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

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
alvardo
  • 157
  • 4
  • 13

5 Answers5

1

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.

Edgar Mejía
  • 119
  • 1
  • 9
  • I am using resolvers to pre-fetch data for the view, so your solution won't be useful to me. Nevertheless, I tried it and the error persist. – alvardo Jun 09 '20 at 21:31
1
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();
      }
    }
}
Shashwat Gupta
  • 5,071
  • 41
  • 33
0

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

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.

daudihus
  • 159
  • 1
  • 8
0
 async showLoading() {
    const loading = await this.loadingCtrl.create({
      message: 'Waiting',
    });
    loading.present();
    loading.addEventListener('ionLoadingDidPresent', (event: any) => {
      console.log('ionLoadingDidPresent')
     //here to do longtime task and close dialog and you will not meet close before open problem
    });
  }
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 14 '22 at 04:38