要旨
我有一个效果,可通过多个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
字符串
答案 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。