Ionic 离子5角加载控制器未捕获(承诺中):覆盖不存在

v9tzhpje  于 2022-12-08  发布在  Ionic
关注(0)|答案(5)|浏览(206)

我正在使用离子5,并试图使用离子LoadingController与解析器。
起初,我遇到的问题是在loadingController.create()完成之前调用了loadingController.dismiss(),所以我按照下面的说明操作:Ionic 4: "Loading Controller" dismiss() is called before present() which will keep spinner without dismissing
因此,我创建了一个服务来显示和关闭加载器,如下所示:

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;
  }
}

我在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();
  }

但我得到以下错误:

13z8s7eq

13z8s7eq1#

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();
      }
    }
}
izj3ouym

izj3ouym2#

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.

3okqufwl

3okqufwl3#

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();
  }
j5fpnvbx

j5fpnvbx4#

这也可能是由于在浏览器中运行您的应用造成的,特别是在使用浏览器设备仿真时(在Chrome中称为“设备工具栏”,在Firefox中称为“响应模式”)。请尝试禁用设备工具栏(Ctrl+Shift+M)或在物理设备上运行您的应用,或者使用适当的仿真器。

5sxhfpxr

5sxhfpxr5#

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
    });
  }

相关问题