Перехват ошибок при вызове API из эффекта NgRx - PullRequest
0 голосов
/ 29 февраля 2020

Я пытаюсь поймать ошибку о влиянии указанного действия c. Все работает нормально, независимо от того, успешен ли вызов или нет. Тем не менее, я думаю, что код очень многословен, и его можно улучшить, особенно:

  • Часть catchError, я возвращаю empty(), но я считаю, что должен возвращать действие SavedReplyDeleteFailed. При этом весь эффект ломается и не компилируется, не уверенный в том, что лучше всего справляться с этим.
  • Я слишком полагаюсь на tap и dispatch вместо того, чтобы возвращать действия из обратные вызовы map / mergeMap. Когда я это делаю, компиляция эффектов также прерывается.

Как я могу применить вышеуказанные улучшения?

    deleteSavedReply = createEffect(() => this.actions$.pipe(
        ofType(SavedRepliesActions.SavedReplyDeleteRequested),
        mergeMap( action => {
            this.store.dispatch( SavedRepliesActions.DeleteLoading({ isLoading: true }) );
            return this.savedRepliesService.deleteSavedReply(action.id).pipe(
                tap(res => {
                    this.store.dispatch( SavedRepliesActions.SavedReplyDeleteSucess({ id: action.id }));
                    this.toastr.success( 'Saved Reply has been successfully deleted');
                }),
                catchError((error) => {
                    this.store.dispatch( SavedRepliesActions.SavedReplyDeleteFailed({message: error.message}) );
                    this.toastr.error( error.message, 'Something went wrong');
                    this.store.dispatch( SavedRepliesActions.DeleteLoading({ isLoading: false }) );
                    return empty();
                })
            );
        }),
        map(() => {
            return SavedRepliesActions.DeleteLoading({ isLoading: false });
        }),
    ));

1 Ответ

1 голос
/ 29 февраля 2020

Вы можете выбрать более реактивный способ (используя Rx JS мощный), и таким образом немного упростить свой код с помощью чего-то вроде этого:

deleteSavedReply$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteRequested),
  mergeMap(action => this.savedRepliesService.deleteSavedReply(action.id).pipe(
    switchMap(res => [
      SavedRepliesActions.SavedReplyDeleteSucess({ id: res.id }),
      UiActions.showToastrSuccess('Saved Reply has been successfully deleted')
    ]),
    catchError(error => of(
      SavedRepliesActions.SavedReplyDeleteFailed({ message: error.message }),
      UiActions.showToastrError(error.message, 'Something went wrong')
    ]))
  ))
))

Для этого в redux мышление, вы должны:

  • Создать 2 новых действия UiActions.showToastrSuccess и UiActions.showToastrError, чтобы показать сообщение Toastr. Отображение сообщения может быть целью для действия.

  • Используйте reducer для вашего loading флага. Это часть вашего состояния, поэтому вместо эффекта следует изменить его значение внутри редуктора.

Например:

on(SavedRepliesActions.SavedReplyDeleteFailed, (state) => ({
  ...state,
  loading: false
})),

on(SavedRepliesActions.SavedReplyDeleteRequested, (state) => ({
  ...state,
  loading: true
})),

Другая опция

Обратите внимание, что другим вариантом (или улучшением ...) может быть отправка Toastr действий внутри действия SavedReplyDeleteSucess. Например:

deleteSavedReply$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteRequested),
  mergeMap(action => this.savedRepliesService.deleteSavedReply(action.id).pipe(
    map(res => SavedRepliesActions.SavedReplyDeleteSucess({ id: res.id }))
    catchError(error => of(SavedRepliesActions.SavedReplyDeleteFailed({ message: error.message })))
  ))
))

savedReplyDeleteSucess$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteSucess),
  map(_ => UiActions.showToastrSuccess('Saved Reply has been successfully deleted'))
))

savedReplyDeleteFailed$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteFailed),
  map(message => UiActions.showToastrError(error.message, 'Something went wrong'))
))

Преимущество здесь в том, что вы можете сделать свой код развивающимся, добавив некоторые дополнительные эффекты в случае успеха или неудачи. например:

savedReplyDeleteFailed$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteFailed),
  switchMap(message => [
    UiActions.showToastrError(error.message, 'Something went wrong')),
    SystemActions.sendTraceError(error)
))

Надеюсь, это поможет.

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