I'm trying to refactor a code that triggers an API request, the error is being caught on the service, I want to catch the error on the component.ts file but for some reason when I try to subscribe to it the success block is being triggered even if it errors out.
The flow is, on component.ts file an action is being triggered, then effects handles it next, and then finally the service which calls the API.
Code:
component.ts
addToCart() {
combineLatest(
this.product$,
this.variantId$,
this.specTemplateStatusAndValue$.pipe(
map((statusAndValue) => statusAndValue.value)
)
)
.pipe(
takeUntil(this.unsubscribe$),
first(),
flatMap(([product, variantId, specTemplateValue]) => {
this.store.dispatch(
this.checkoutActions.addToCart(
variantId,
product.normal_product ? 1 : 1,
specTemplateValue,
[]
)
);
return of(null);
})
)
.subscribe(
(res) => {
console.log('subs', res);
return this.router.navigate(['/checkout', 'cart']);
},
(err) => console.error(':::::ERROR', err)
);
}
action.ts
addToCart(
variant_id: number,
quantity: number,
spec_template_value: any = {},
addon_value_ids = []
): any {
return {
type: CheckoutActions.ADD_TO_CART,
payload: {
variant_id,
quantity,
spec_template_value,
addon_value_ids: addon_value_ids
}
};
}
effect.ts
@Effect()
addToCart$ = this.actions$.pipe(
ofType(CheckoutActions.ADD_TO_CART),
flatMap((action: any) => {
return this.checkoutService.createNewLineItem(action.payload);
}),
map((result) => {
return this.actions.addToCartSuccess();
})
);
service.ts
createNewLineItem(payload) {
return of(null).pipe(
tap(() => {
this.store.dispatch(this.actions.loadingCurrentOrder());
}),
flatMap(() => this.fetchCurrentOrder()),
flatMap((order) => {
console.log(order, 'ASDASD');
return this.http.post<Order>(
`spree/api/v1/orders/${order.number}/line_items?order_token=${order.token}`,
this.createLineItemPayload({
variant_id: payload.variant_id,
quantity: payload.quantity,
spec_template_value: payload.spec_template_value,
addon_value_ids: payload.addon_value_ids,
coupon_claim_id: payload.coupon_claim_id
})
);
}),
tap((order) => {
this.store.dispatch(this.actions.fetchCurrentOrderPreProcess(order));
}),
finalize(() => {
this.store.dispatch(this.actions.loadedCurrentOrder());
})
);
}
You won't be able to catch directly the error on the component since you dispatching an effect (which is synchronous).
Your alternative is to:
actions$
in the component).