Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why LoadingController throws 'Overlay does not exist ' when trying to dismiss it during an API call

I have a created a service for an custom loading controller with the following methods:

    async showLoader(){
        //Show cutom loader
        this.loadingController.create({
          message: 'Loading...',
          cssClass: 'loader-css-class'
        }).then((res) => {
          return res.present();
        });
      }
     
      async dismissLoader(){
        //Hide cutome loder
        this.loadingController.dismiss().then((response) =>{
          console.log("Loader closed: ", response);
        }).catch((err) => {
          console.log('Errro occured closing loader: ' + err);
        });
     }

The service is used and load controller called when prior to an API request is made, and dismissed when the API call returned data :

    constructor(
       public loadingController : LoadControllerServiceService){}

The API call is made from ngOnInIt:

ngOnInit(){

    this.getData();
   
 }

This method makes an API call :

    getData(){
       //get data form remote serve using service
       console.log("conatct.ts: get all conatcts");
      
       this.loadingController.showLoader();
       this.service.getAll().subscribe(data => {
        
         this.allDepartments = data;
         this.allDepartmentsOriginal = this.allDepartments;
         this.loadingController.dismissLoader();
    
         //itearte array and assign bsepearte departmental contacts 
       console.log("contacts.page.ts: trting to get biohemistry  data...");
        for (var contact of this.allDepartments){
         ...
         ...
        }
    
    }

I have looked at this answer and various other answers but can't seem to get load / dismiss right as I keep getting the exception: overlay does not exist.

Any input appreciated.

like image 519
dancingbush Avatar asked Sep 03 '25 16:09

dancingbush


1 Answers

The problem that u have met is async issue, loadingController.create races with getData, they are both async.

First u should write u functions, that will return obs. for futher chaining

function showLoader() {
  //Show custom loader
  return from(this.loadingController.create({
    message: 'Loading...',
    cssClass: 'loader-css-class'
  })).pipe(map(res => res.present));
}

function dismissLoader() {
  this.loadingController.dismiss()
}

Than u should chain u function calls to pipe

function getData(){
  //get data form remote serve using service
  console.log("conatct.ts: get all conatcts");

  this.showLoader().pipe(
    switchMap(_ => {
      return this.service.getAll()
    }),
    finalize(() => this.dismissLoader())
  ).subscribe(data => {
    this.allDepartments = data;
    this.allDepartmentsOriginal = this.allDepartments;
  });
}

ps.

  1. It's bad practice to mix rxjs and promises, u should transform promise calls to observables.
  2. In angular for proper detect change and other stuff, u should use rxjs
like image 178
Дмитрий Васильев Avatar answered Sep 05 '25 08:09

Дмитрий Васильев