Angular2,RxJS 主题 http 请求 - 错误请求不会再次触发
Angular2, RxJS Subject http request - On error request wont fire again
我在收到 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();
单击按钮时,我创建一个 payload/object 并像这样传入:
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
}
});
您遇到的问题归结为 "The Observable contract"。一个链只能发出一个错误通知,因此当您的 this.bookingService.update
发出错误时,该链将被处理(取消订阅)。因此,从 saveBookingObservable
发出更多 next
通知没有任何效果。
根据您的具体需求,您似乎可以在 switchMap()
之后附加 retry()
,这将自动重新订阅。
我在收到 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();
单击按钮时,我创建一个 payload/object 并像这样传入:
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
}
});
您遇到的问题归结为 "The Observable contract"。一个链只能发出一个错误通知,因此当您的 this.bookingService.update
发出错误时,该链将被处理(取消订阅)。因此,从 saveBookingObservable
发出更多 next
通知没有任何效果。
根据您的具体需求,您似乎可以在 switchMap()
之后附加 retry()
,这将自动重新订阅。