Angular Ngrx:具有副作用的后卫

时间:2018-12-05 12:44:55

标签: angular typescript ngrx angular-router-guards ngrx-entity

如果这是某个问题的答案,我最近感到很抱歉,但是找不到解决我问题的方法。

我有警惕,现在我需要从副作用中捕获错误,该副作用会调用http服务,并将用户重定向到错误状态。试图添加catchError,但是如果从服务器端收到错误消息,我什至不去那里。

guard.ts

canActivate(): Observable<boolean> {
    return this.store
        .select(fromDataStore.getDatasLoaded)
        .pipe(
            withLatestFrom(this.store.select(fromDataStore.getDataLoading)),
            map(([loaded, loading]) => {
                if (!loaded && !loading) {
                    this.store.dispatch(new fromDataStore.LoadData());
                }
                return loaded;
            }),
            filter(loaded => loaded),
            take(1),
            catchError(error => {
                // redirect user to error state
            })
        );
}

effect.ts

 @Effect() loadData$: Observable<Action> = this.actions$.ofType(DataActionTypes.LoadData)
    .pipe(
        mergeMap(() =>
            this.dataApiService.loadData()
                .pipe(
                    map(data => ({
                        type: DataActionTypes.LoadDataSuccess,
                        payload: data
                    })),
                    catchError(() => of({ type: DataActionTypes.LoadDataFailure }))
                )
        )
    );

reducer.ts

case DataActionTypes.LoadData: {
        return {
            ...state,
            data: {
                ...state.data,
                isLoading: true
            }
        };
    }
    case DataActionTypes.LoadDataSuccess: {
        return {
            ...state,
            data: {
                ...dataAdapter.addMany(action.payload, state.data),
                isLoaded: true,
                isLoading: false
            }
        };
    }
    case DataActionTypes.LoadDataFailure: {
        return {
            ...state,
            data: {
                ...state.data,
                isLoaded: true,
                isLoading: false
            }
        };
    }
    default: {
        return state;
    }

1 个答案:

答案 0 :(得分:3)

在化简器中处理LoadDataFailure时,可以将错误添加到状态中。

在后卫中,您可以添加withLatestFrom并选择该状态的一部分,并显示错误信息。这里没有错误,而不是catchError,因此它不会捕获任何东西。

如果没有错误,则可以导航到页面,如果有错误,则将用户重定向到所需的内容。

您还可以重构一些代码,例如总是在防护进入时触发加载操作,将if语句移到外部并使用isDataLoaded流。

类似的东西:

this.store.dispatch(new fromDataStore.LoadData());

return this.store
        .select(fromDataStore.getDatasLoaded)
        .filter(Boolean),
        .withLatestFrom(fromDataStore.getError)
        ...