Reputation: 83
I have an issue when receiving an http error response (422 validation error from backend).
Once an http error response is received, I can't fire the request again (on button click).
1) I have a subject property, and I call .next(whatEverDataForTheRequest), in order to kick of the request to the API.
2) In the constructor I subscribe to the subject (.asObservable), and here everything goes fine whenever the response is succesfull, but not when an error happens.
Code is currently like this:
// Properties -> Subject + Observable, used when button is clicked
private saveBookingSubject: Subject<BookingUpdateInterface> = new Subject<BookingUpdateInterface>();
private saveBookingObservable = this.saveBookingSubject.asObservable();
When button is clicked, I create a payload/object and pass in like this:
this.saveBookingSubject.next(payload)
Then in the constructor, I have the following code which gets triggered when .next gets called.
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);
});
Successful request works as intended - But when an error is received from backend, then the call to:
this.saveBookingSubject.next(payload)
...is completely ignored, whenever the button gets clicked -> And the subscription logic never kicks in.
What am I missing here? (I do unsubscribe in ngOnDestroy)
Thanks!
EDIT EDIT - WORKING EXAMPLE (as posted by 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
}
});
Upvotes: 2
Views: 918
Reputation: 96891
The problem you have comes down to "The Observable contract". One chain can emit only one error notification so when your this.bookingService.update
emits an error the chain is disposed (unsubscribed). Emitting more next
notifications from saveBookingObservable
has therefore no effect.
Depending on what you want exactly you want to do it seems like you could just append retry()
after switchMap()
that will automatically resubscribe.
Upvotes: 4