2

收到 http 错误响应(来自后端的 422 验证错误)时出现问题。

收到 http 错误响应后,我无法再次触发请求(单击按钮)。

1) 我有一个主题属性,我调用 .next(whatEverDataForTheRequest),以便启动对 API 的请求。

2)在构造函数中,我订阅了主题(.asObservable),只要响应成功,这里就一切正常,但发生错误时就不行了。

代码目前是这样的:

// Properties -> Subject + Observable, used when button is clicked
private saveBookingSubject: Subject<BookingUpdateInterface> = new Subject<BookingUpdateInterface>();
private saveBookingObservable = this.saveBookingSubject.asObservable();

单击按钮时,我创建一个有效负载/对象并像这样传入:

this.saveBookingSubject.next(payload)

然后在构造函数中,我有以下代码,当调用 .next 时会触发这些代码。

const sub = this.saveBookingObservable.pipe(
  tap(data => {
    this.bookingError = null;
    this.dialogCanClose = false;
  }),
  debounceTime(500),
  switchMap(booking => {
    return this.bookingService.update(booking).pipe(catchError(error => throwError(error)));
  })
).subscribe((response: any) => {
  // This works - Called on success
  console.log('ok', response);
}, (http: HttpErrorResponse) => {
  // This works - Gets called on error
  console.log(http);
});

成功的请求按预期工作 - 但是当从后端收到错误时,调用:

this.saveBookingSubject.next(payload)

...被完全忽略,每当单击按钮时 - >订阅逻辑永远不会启动。

我在这里想念什么?(我在 ngOnDestroy 中取消订阅)

谢谢!


编辑编辑 - 工作示例(由 Martin 发布)

const sub = this.saveBookingObservable.pipe(
  debounceTime(500),
  switchMap(booking => {
    return this.bookingService.update(booking).pipe(
      catchError(httpError => {
        this.bookingError = httpError.error.data;
        return of(null);
      })
    );
  }),
  retry(1)
).subscribe((response: any) => {
    // Handle success
  }
});
4

1 回答 1

2

您遇到的问题归结为"The Observable contract"。一条链只能发出一个错误通知,因此当您this.bookingService.update发出错误时,该链将被处置(取消订阅)。因此,发出更多next通知是saveBookingObservable无效的。

根据您想要做什么,您似乎可以在retry()之后switchMap()自动重新订阅。

于 2020-01-26T17:39:39.490 回答