angular - Angular 6。 httpClient中错误处理的正确方法

标签 angular typescript error-handling rxjs

我想知道可观察流中的错误处理。我阅读了有关在Angular中使用rxjs和异步管道的文章。它写在这里,我们应该避免使用订阅运算符,并尝试将其替换为异步管道。但是现在当我尝试编写一些发布/发布请求时,我们必须订阅,因此我在应该修改组件状态的地方有些困惑。

submitForm() {
  this.restService.add(this.user.id, this.form.value)
    .pipe(
      tap(() => { this.isAdded = true }),
      catchError((error: HttpErrorResponse) => {
          this.responseMsg = 'Something went wrong'
          return throwError('notFound')
        }
      )
    ).subscribe();
  }

还是我应该在订阅中处理
submitForm() {
      this.restService.add(this.user.id, this.form.value)
        .pipe(
          tap(() => { this.isAdded = true }),
        ).subscribe( 
            () => {}, 
            () => {this.responseMsg = 'Something went wrong'}
       );
 }

哪种解决方案更好?

最佳答案

这就是您正确使用异步管道的方式。当您使用异步管道时,您无需订阅,因为它们为您执行了可观察的生命周期。订阅并销毁订阅,以避免内存泄漏。如果您不使用异步管道,则必须手动执行。

SERVICE.TS

import { EquipmentID } from './../../../shared/model/equipmentID.model';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { PickupAvailability } from '../models/pickup-availability.model';
import { catchError } from 'rxjs/operators';
import { ErrorHandlingService } from '../../../shared/services/error-handling.service';
@Injectable()
export class PickupAvaibilityService {
  BASE_URL = '/sxrw-ship/api/v1';
  AMOUNT_DUE_URL = '/shipments/search';

  constructor(
    private http: HttpClient,
    private errorHandler: ErrorHandlingService
  ) {}

  getAmountDue(equipmentID: EquipmentID[]): Observable<PickupAvailability> {
    return this.http
      .post<PickupAvailability>(
        this.BASE_URL + this.AMOUNT_DUE_URL,
        equipmentID
      )
      .pipe(catchError(this.errorHandler.handleError));
  }
}

然后在我的自定义错误处理程序服务中,您将获得以下内容:

ERRORHANDLER.SERVICE.TS
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { _throw } from 'rxjs/observable/throw';
@Injectable()
export class ErrorHandlingService {
  constructor() {}

  handleError(error: HttpErrorResponse) {
    //To know the version of RxJS npm list --depth=0 (I for this example im on version 5.5)
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred: ', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}` + ` body was: ${error.message}`
      );
    }
    // return an observable with a user-facing error message
    return _throw('Something bad happened; please try again later.');
  }
}

我做错误处理程序的方式是在Angular的官方网站https://angular.io/guide/http上完成的方式

现在,在将使用调用我们http的服务的组件中,您声明一个Observable类型的变量(使用$ sing是一个好习惯)

COMPONENT.TS
pickupAvailability$: Observable<PickupAvailability>;

  getPickupDate(pa: PickupAvailability) {
    let id = pa.equipmentInitial + pa.equipmentNumber;
    this.equipmentSummary$ = this.pickupDateService
      .getPickupDate(id)
      .pipe(
        map(
          pd =>
            new EquipmentSummary(
              id,
              pd.pickupDate,
              'TODO',
              pa.totalPremiseCharges
            )
        )
      );
  }

HTML
<div *ngIf="(pickupAvailability$ | async) as pickupAvailability">
  <!-- TODO move to table -->
  <div *ngFor="let pa of pickupAvailability">
    <button pButton type="button" label="Pay ${{ pa.totalPremiseCharges }}" class="x-primary-gray-100" (click)='getPickupDate(pa)'>
    </button>
  </div>
  <div *ngIf="(equipmentSummary$ | async) as es">
    <app-pay-storage [equipmentSummary]="es"></app-pay-storage>
  </div>
</div>

您可以通过执行以下操作进行测试:
{{pickupAvailability$ | async | json}}

当您实际使用它时,请删除json管道

关于angular - Angular 6。 httpClient中错误处理的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52030474/

相关文章:

html - 将 String 附加到 ngModel 以获取表达式

javascript - 如何重写函数中的接口(interface)并保持正确的返回类型?

sockets - 如何找到已经在使用的地址?

flutter - 如何解决Build失败并出现异常?

angular - 如何使用 Angular 8.0.2 隐藏 API key

angular - 使用 Angular 4 在单个组件中加载动态模板

javascript - 在行分组级别 ag-grid 启用单元格字段的编辑

css - 如何强制 Office UI Fabric ChoiceGroup 水平对齐

Angular 7路由连接导致编译错误

error-handling - 如果SQL Server没有加密,则VB6使用crypto = true管理错误