NGRX/Effects 将数据传递给 catchError
NGRX/Effects pass data through to catchError
要点
我有一个效果,通过多个 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,
}))),
);
问题
问题是,我不知道如何从 catchError
中的第一个 switchMap
访问 productId
字符串
只需将下一个运算符嵌套在第一个 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 方法 returns 一个承诺:
return from(this.reviewsService.loadOfProduct(productId)) // originally fromPromise
.pipe(...)
这也是处理 effects 内部错误的正确方法,因为在原始代码中,如果发生错误,"effect" 将停止工作,即使它进入了 catchError 运算符。
有关此内容的更多信息,请查看 。
要点
我有一个效果,通过多个 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,
}))),
);
问题
问题是,我不知道如何从 catchError
switchMap
访问 productId
字符串
只需将下一个运算符嵌套在第一个 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 方法 returns 一个承诺:
return from(this.reviewsService.loadOfProduct(productId)) // originally fromPromise
.pipe(...)
这也是处理 effects 内部错误的正确方法,因为在原始代码中,如果发生错误,"effect" 将停止工作,即使它进入了 catchError 运算符。
有关此内容的更多信息,请查看