Angular2, Rx JS Тема http запроса - При ошибке запрос не будет запускаться снова - PullRequest
1 голос
/ 26 января 2020

У меня проблема при получении ответа об ошибке 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)

... полностью игнорируется, когда нажимается кнопка -> И логика подписки c никогда не срабатывает дюйма

Что мне здесь не хватает? (Я отписываюсь в ngOnDestroy)

Спасибо!


РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ - РАБОЧИЙ ПРИМЕР (опубликовано Мартином)

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
  }
});

1 Ответ

1 голос
/ 26 января 2020

Ваша проблема сводится к "Наблюдаемый контракт" . Одна цепочка может отправлять только одно уведомление об ошибке, поэтому, когда ваш this.bookingService.update выдает ошибку, цепочка удаляется (отписывается). Поэтому отправка next уведомлений из saveBookingObservable не имеет никакого эффекта.

В зависимости от того, что именно вы хотите делать, похоже, что вы можете просто добавить retry() после switchMap(), что автоматически повторяет подписку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...