Accessing state in an NGRX effect
Asked Answered
I

2

10

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.

Insatiable answered 17/10, 2018 at 5:13 Comment(1)
Have a look at This question. It should get you going. Be sure to check Martin's answer on more explanation on the correct operator.Trimetric
F
9

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))
                        )
                    );
            }
        )
    );
Flotage answered 7/8, 2020 at 14:19 Comment(0)
V
2

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)

Vilberg answered 22/10, 2018 at 20:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.