NGRX /效果将数据传递到catchError

时间:2018-08-08 17:30:38

标签: redux rxjs observable ngrx ngrx-effects

要旨

我有一个效果,可通过多个API请求加载产品评论:

@Effect()
    loadOfProduct$ = this.actions$.pipe(
        ofType<ReviewsActions.LoadOfProduct>(ReviewsActions.Types.LOAD_OF_PRODUCT),
        map(action => action.payload),
        switchMap((productId: string) => {
            return this.reviewsService.loadOfProduct(productId);
        }),
        switchMap((reviews: Review[]) => {
            return forkJoin([
                of(reviews),
                this.productsService.loadManyById(reviews.map(r => r.productId)),
                this.usersService.loadManyById(reviews.map(r => r.writerId)),
            ]);
        }),
        switchMap((data: any) => {
            const [reviews, products, users] = data;
            return [
                new ProductsActions.LoadManyByIdSuccess(products),
                new UsersActions.LoadManyByIdSuccess(users),
                new ReviewsActions.LoadOfProductSuccess(reviews),
            ];
        }),
        catchError(error => of(new ReviewsActions.LoadOfProductFail({
            ...error.error,
            // I need the productId here!!!
            // payload: productId,
        }))),
    );

问题

问题是,我不知道如何从productId的第一个switchMap访问catchError字符串

1 个答案:

答案 0 :(得分:4)

将下一个运算符简单地嵌套在第一个switchMap下:

    @Effect() loadOfProduct$ = this.actions$
    .pipe(
        ofType<ReviewsActions.LoadOfProduct>(ReviewsActions.Types.LOAD_OF_PRODUCT),
        switchMap((action) => {
            const productId = action.payload;
            return this.reviewsService.loadOfProduct(productId)
                .pipe(
                    switchMap((reviews: Review[]) => {
                        return forkJoin([
                            of(reviews),
                            this.productsService.loadManyById(reviews.map(r => r.productId)),
                            this.usersService.loadManyById(reviews.map(r => r.writerId)),
                        ]);
                    }),
                    switchMap((data: any) => {
                        const [reviews, products, users] = data;
                        return [
                            new ProductsActions.LoadManyByIdSuccess(products),
                            new UsersActions.LoadManyByIdSuccess(users),
                            new ReviewsActions.LoadOfProductSuccess(reviews),
                        ];
                    }),
                    catchError(error => of(new ReviewsActions.LoadOfProductFail({
                        ...error.error,
                        // now you have the productId
                        // payload: productId,
                    })))
                );
        })
    );

或者,如果reviewsService.loadOfProduct方法返回一个Promise:

return from(this.reviewsService.loadOfProduct(productId)) // originally fromPromise
    .pipe(...)

这也是处理特效内部错误的正确方法,因为在原始代码中,如果发生错误,即使进入catchError运算符,“特效”也将停止工作。

有关更多信息,请查看ngrx effects error handling