从ngrx效果调用API时捕获错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从ngrx效果调用API时捕获错误相关的知识,希望对你有一定的参考价值。

我正在尝试捕获有关特定操作效果的错误。无论调用成功还是失败,一切都正常。但是,我认为代码非常冗长,可以对其进行改进,特别是:

  • catchError部分,我返回empty(),但我认为应该返回SavedReplyDeleteFailed操作。这样做时,整个效果会中断并且无法编译,请不确定如何处理此效果的最佳方法。
  • 我过于依赖tapdispatch,而不是从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 });
        }),
    ));

答案

您可以使用类似以下的代码来简化您的代码:

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.showToastrSuccessUiActions.showToastrError以显示消息Toastr。显示消息是操作的可能目标。

  • reducer标志中使用loading。这是状态的一部分,因此应在化简器中更改其值以代替效果。

例如:

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

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

希望它会有所帮助。

以上是关于从ngrx效果调用API时捕获错误的主要内容,如果未能解决你的问题,请参考以下文章

在使用 NGRX 使用 observables 调用 API 之前检查 Angular Store 中的数据

从片段捕获图像时从不调用onActivityResult [重复]

如何调用两次在ngrx效果中调用的服务?

服务器上取消了多个 API 调用

NgRx 效果加载两​​次

Angular ngrx + Firebase OAuth 操作已调用但效果不