簡體   English   中英

無法在 Subscribe() 的錯誤響應中關閉 LoadingController - Ionic 4

[英]Cannot Dismiss LoadingController In Error Response Of Subscribe() - Ionic 4

當用戶嘗試登錄時,我正在顯示 LoadingController。 同時,正在調用 API。

當我收到來自訂閱的 SUCCESS 響應時,我可以關閉 LoadingController,但是當我收到 ERROR 響應時,我無法關閉。 請幫忙!

我是一名專業的 Python 開發人員,也是 Ionic 的新手,一天前剛剛開始。 所以,請協助。

import { Component, OnInit } from '@angular/core';
import { ToastController, LoadingController } from '@ionic/angular';

import { CallapiService } from '../callapi.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {

  userEmail = '';
  userPassword = '';
  loginUrl = 'login/';
  loginMethod = 'POST';
  postBody = {};


  constructor(
    public toastController: ToastController,
    public loadingController: LoadingController,
    private callApiService: CallapiService,
  ) { }

  ngOnInit() {
  }

  async presentToast(displayMessage) {
    const toast = await this.toastController.create({
      message: displayMessage,
      duration: 2000,
      position: 'middle',
    });
    return await toast.present();
  }

  async presentLoading(loadingMessage) {
    const loading = await this.loadingController.create({
      message: loadingMessage,
    });
    return await loading.present();
  }


  loginUser() {
    if (this.userEmail === '' || this.userPassword === '') {
      this.presentToast('Email and password are required.');
    }

    else {
      this.presentLoading('Processing...');
      this.postBody = {
        email: this.userEmail,
        password: this.userPassword,
      };
      this.callApiService.callApi(this.loginUrl, this.postBody, this.loginMethod).subscribe(
        (success) => {
          console.log(success);
          this.loadingController.dismiss();
        },
        (error) => {
          console.log(error);
          this.loadingController.dismiss();
        }
      );
      this.loadingController.dismiss();
    }

  }

}

沒有任何服務,

我在使用 Ionic 4 加載控制器時遇到的同樣問題。 經過反復試驗,我得到了有效的解決方案。

由於加載控制器函數使用 async 和 await,因為它們都是異步函數。

dismiss() 函數將在 present() 函數之前調用,因為dismiss 函數不會等到創建和呈現加載器,它會在present() 函數調用之前觸發。

下面是工作代碼,

   loading:HTMLIonLoadingElement;
   constructor(public loadingController: LoadingController){}

   presentLoading() {
     if (this.loading) {
       this.loading.dismiss();
     }
     return new Promise((resolve)=>{
       resolve(this.loadingController.create({
        message: 'Please wait...'
      }));
     })
   }

  async dismissLoading(): Promise<void> {
    if (this.loading) {
      this.loading.dismiss();
    }
  }

  someFunction(){
    this.presentLoading().then((loadRes:any)=>{
      this.loading = loadRes
      this.loading.present()

      someTask(api call).then((res:any)=>{
        this.dismissLoading();
      })
    })
  }
this.callApiService.callApi(this.loginUrl, this.postBody, this.loginMethod)
  .subscribe(
    (data) => {
      // Called when success  
    },
    (error) => {
      // Called when error
    },
    () => {
      // Called when operation is complete (both success and error)
      this.loadingController.dismiss();
    });

來源: https : //stackoverflow.com/a/54115530/5442966

使用 Angular 屬性綁定。 為您的加載創建一個組件:

import { Component, Input } from '@angular/core';
import { LoadingController } from '@ionic/angular';

@Component({
  selector: 'app-loading',
  template: ''
})
export class LoadingComponent {
  private loadingSpinner: HTMLIonLoadingElement;

  @Input()
  set show(show: boolean) {
    if (show) {
      this.loadingController.create().then(loadingElem => {
        this.loadingSpinner = loadingElem;
        this.loadingSpinner.present();
      });
    } else {
      if (this.loadingSpinner) {
        this.loadingSpinner.dismiss();
      }
    }
  }

  constructor(private loadingController: LoadingController) {}
}

...然后在“login.page.html”中使用您的組件:

...    
<app-loading [show]="showLoading"></app-loading>

...在“登錄頁面”中創建一個屬性“showLoading”並將其設置為 true 或 false 您想要的:

//.... some source code
export class LoginPage implements OnInit {
  showLoading;
  userEmail = '';
  userPassword = '';
  loginUrl = 'login/';
  loginMethod = 'POST';
  postBody = {};

  //.... some source code

  loginUser() {
    if (this.userEmail === '' || this.userPassword === '') {
      this.presentToast('Email and password are required.');
    } else {
      this.showLoading = true;
      this.postBody = {
        email: this.userEmail,
        password: this.userPassword
      };
      this.callApiService
        .callApi(this.loginUrl, this.postBody, this.loginMethod)
        .subscribe(
          success => {
            console.log(success);
            this.showLoading = false;
          },
          error => {
            console.log(error);
            this.showLoading = false;
          }
        );
      this.showLoading = false;
    }
  }
}

這對我有用,我在其他頁面上重用加載組件!

推薦閱讀: https : //angular.io/start

我實際上遇到了這個確切的問題,對我來說答案就是使用await

用於創建和解除加載器的函數返回承諾。 我意識到正在發生的是訂閱/承諾拒絕正在阻止所有其他承諾完成。 現在,我只是等待呈現和解散,我沒有問題:

async getData() {  
  //await presenting
  await this.presentLoading('Loading...');

  try {
    let response = await this.httpService.getData();
    await this.loadingController.dismiss();

    //...
  catch(err) {
    this.loadingController.dismiss();
    //handle error
    //...
  }
}

async presentLoading(msg: string) {
  const loading = await this.loadingController.create({
    spinner: 'crescent',
    message: msg
  });
  await loading.present();
}

我希望這個簡單的解決方案有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM