Search code examples
asynchronousngrxngrx-effects

ngrx effect - waiting on external data


I have an effect which runs when a user is downloaded and stored in state:

getMetadata$ = createEffect(() => {
  return this.actions$.pipe(
    ofType(fromUserSelectors.getUserSuccess),
    concatLatestFrom(() => this.store.select(fromProductSelectors.selectProduct)),
    exhaustMap(([user, product]) =>
      // do something with user and product
    )
  );
});

This effect is triggered when getUserSuccess is dispatched.

However, you can see on the 4th line, I also need the product which is stored in a different store and is downloaded asynchronously to the user being downloaded. So it isn't necessarily populated until later.

How can I tell this effect to wait for the product to be populated before resuming? I do not want to retrigger the effect. I thought that was the purpose of concatLatestFrom introduced in ngrx v12, but maybe I am misunderstanding it.

I am aware I could have multiple actions being listened to in my ofType call and listen to fromProductSelectors.getProductSuccess, but I only want this effect to run when getUserSuccess is called, not fromProductSelectors.getProductSuccess too, but need the selectProduct to not be undefined.


Solution

  • You can use the filter operator to wait until it becomes available.

    getMetadata$ = createEffect(() => {
      return this.actions$.pipe(
        ofType(fromUserSelectors.getUserSuccess),
        concatLatestFrom(() => this.store.select(fromProductSelectors.selectProduct).pipe(filter(x => !!x)),
        exhaustMap(([user, product]) =>
          // do something with user and product
        )
      );
    });