Search code examples
rxjsngrxngrx-storengrx-effects

Need help understanding this Ngrx effect


The Ngrx documentation for using an effect with state selected from the store states (no pun intended)

Note: For performance reasons, use a flattening operator like concatMap to prevent the
selector from firing until the correct action is dispatched.

...and provides the example:

    addBookToCollectionSuccess$ = createEffect(() => this.actions$.pipe(
      ofType(CollectionApiActions.addBookSuccess),
      concatMap(action => of(action).pipe(
          withLatestFrom(this.store.select(fromBooks.getCollectionBookIds))
      )),
      tap(([action, bookCollection]) => console.log('whatever'))
      ), { dispatch: false }
    );

The example has since been changed to use concatLatestFrom, but that's not important here. What I'm interested in is understanding the original suggestion. I think I understand the intent, to avoid having withLatestFrom processing results from getCollectionBookIds apart from when the source action triggers, but I don't understand why the solution needs to involve wrapping withLatestFrom in a manually constructed Observable using of(action). Wouldn't something like this be just as effective and a lot more readable?

    concatMap(() => this.store.select(selectSelectedBookIds).pipe(first())),

My understanding of Rxjs is not that good and after a few days of trying to working this out I suspect I'm still missing something.


Solution

  • Your suggestions should work fine, if you just need the selected state:

    concatMap(() => this.store.select(selectSelectedBookIds).pipe(first())),
    

    However, should you also need the action itself, the following will pass along an array containing both the action and your selected state:

    concatMap(action => of(action).pipe(
      withLatestFrom(this.store.select(fromBooks.getCollectionBookIds))
    )),