In my Angular app, I want to stop calling the server using the ProductService
which has http
if the store has already the data.
This is what I currently have. I get a stream from the store and check whether the store has products. If the store has already products, return that data. Otherwise proceed the flow, get the categoryId
, call the server using the ProductService
and return the data.
Am I doing the effect correctly?
loadProducts$ = createEffect(
() => ({ debounce = 300, scheduler = asyncScheduler } = {}) =>
this.actions$.pipe(
ofType(ProductActions.LoadProducts),
debounceTime(debounce, scheduler),
switchMap(() => this.ProductStore.pipe(select(ProductSelectors.selectAllProducts))),
switchMap((Products) => {
if (Products.length != 0) {
return ProductActions.LoadProductsSuccess({ Products });
}
return of(ProductActions.LoadProductsCancelled({ Products }));
}),
switchMap(() => this.store.pipe(select(fromRoots.getCategory))),
switchMap((category) =>
this.ProductService.getProducts(category.categoryId).pipe(
map(Products => (ProductActions.LoadProductsSuccess({ Products }))),
catchError(err => of(ProductActions.LoadProductsFailed(err))
)
))));
I updated the effect per Flignats suggestion, and is follows:
loadProducts$ = createEffect(
() => ({ debounce = 300, scheduler = asyncScheduler } = {}) =>
this.actions$.pipe(
ofType(ProductActions.LoadProducts),
debounceTime(debounce, scheduler),
withLatestFrom(
this.store.select(ProductSelectors.selectAllProducts),
this.rootState.select(fromRoots.getcategory),
),
switchMap(([action, existingProducts, category]) => {
if (existingProducts.length > 0) {
return of(ProductActions.LoadProductsSuccess({ Products: existingProducts }));
}
return this.ProductService.getProducts(category.categoryId).pipe(
map(newProducts => (ProductActions.LoadProductsSuccess({ Products: newProducts }))),
catchError(err => of(ProductActions.LoadProductsFailed(err)))
)
})));