How can I access a piece of my state inside an effect? My current effect implementation (shown below) is triggered when a SEARCH_REUQUEST
action is dispatched. However, I would like to access a piece of state to fetch some search parameters before calling my search service to initiate the HTTP request.
@Effect()
SearchRequest$ = this.actions$
.ofType(fromSearchActions.SearchActionTypes.SEARCH_REQUEST)
.pipe(
switchMap((action: fromSearchActions.SearchRequest) => {
return this.searchService
.search(action.payload, action.enrichmentId)
.pipe(
map(response => {
console.group("SEARCH effects");
console.log(response);
console.groupEnd();
return new fromSearchActions.SearchRequestSuccess(response);
}),
catchError(error =>
of(new fromSearchActions.SearchRequestFail(error))
)
);
})
);
Apparently there is an RxJS operator that I can take advantage of here, but I can't seem to understand how I'd go about modifying my existing effect implementation to incorporate that.
@Effect()
SearchRequest$ = this.actions$
.ofType(fromSearchActions.SearchActionTypes.SEARCH_REQUEST)
.withLatestFrom(this.featureStore.select(fromFeature.getCurrentSearchPageOptions))
.pipe(
switchMap((// How should this change? //) => { //Error
return this.searchService
.search(action.payload, action.enrichmentId, pageOptions)
.pipe(
map(response => {
console.group("SEARCH effects");
console.log(response);
console.groupEnd();
return new fromSearchActions.SearchRequestSuccess(response);
}),
catchError(error =>
of(new fromSearchActions.SearchRequestFail(error))
)
);
})
)
I feel like I am close to a solution but I can't seem to put it together at the switchMap
stage.
The idea is to inject a Storage instance into the Effect. Then, you can use it in your effect factory method. Now, you can use your storage object to get data from your current state. (You can use a Selector.)
Where Does NgRx Store Data? NgRx stores the application state in an RxJS observable inside an Angular service called Store. At the same time, this service implements the Observable interface. So, when you subscribe to the store, the service actually forwards the subscription to the underlying observable.
You need to run this command npm install @ngrx/effects — save to install required dependencies. You have to define the actual services to make the API calls. Finally, you need to register all the effects with the EffectsModules and import this module into your main module or feature module.
When should you not use NgRx? Never use NgRx if your application is a small one with just a couple of domains or if you want to deliver something quickly. It comes with a lot of boilerplate code, so in some scenarios it will make your coding more difficult.
withLatestFrom: Combines the source Observable with other Observables to create an Observable whose values are calculated from the latest values of each.
You will get an array with the two data, you can find a guide in https://medium.com/@viestursv/how-to-get-store-state-in-ngrx-effect-fab9e9c8f087
your code could be like this:
@Effect()
SearchRequest$ = this.actions.pipe(
ofType(fromSearchActions.SearchActionTypes.SEARCH_REQUEST),
withLatestFrom(this.featureStore.select(fromFeature.getCurrentSearchPageOptions)),
switchMap(([action: Action, pageOptions: YourStateOptions]) => { // <-- pageOptions here
return this.searchService
.search(action.payload, action.enrichmentId, pageOptions)
.pipe(
map(response => {
console.group("SEARCH effects");
console.log(response);
console.groupEnd();
return new fromSearchActions.SearchRequestSuccess(response);
}),
catchError(error =>
of(new fromSearchActions.SearchRequestFail(error))
)
);
}
)
);
withLatestFrom is definitely what you want. All you have to do is add the response to the parameters you pass in the switchMap. Like this (where pageOptions is the type for the slice of state you get from your selector):
switchMap(([action, options]: [fromSearchActions.SearchRequest, pageOptions]) => {
then you can use action
as you did before and options
would be what you get back from this.featureStore.select(fromFeature.getCurrentSearchPageOptions)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With