Search code examples
angularrxjsngrx

Rxjs - condition pipeable operator


I'm using Angular and Ngrx. I'm retrieving lots of data from my backend in many seperate calls; 2 pieces of the data in my Ngrx store state are dashboardState.issuesState.issues and dashboardState.defaultAssetId.

I have the following code to call the 'setCurrentlySelectedAsset' method:

this.store.pipe(
      select((state: AppState) => state.dashboard.defaultAssetId),
      tap((selectedAssetId: number) => this.setCurrentlySelectedAsset(selectedAssetId))
    ).subscribe();

This works, and the setCurrentlySelectedAsset method is called every time state.dashboard.defaultAssetId emits a value, great.

But I only want this method to be called IF dashboardState.issuesState.issues has a value (i.e. the backend request has been completed).

A possible solution could be this:

this.store.pipe(
      select((state: AppState) => state.dashboard),
      tap((dashboardState: State) =>
      {
        if (dashboardState.issuesState.issues && dashboardState.defaultAssetId)
        {
          this.setCurrentlySelectedAsset(dashboardState.defaultAssetId)
        }
      })
    ).subscribe();

But now my tap will be called every time anything on dashboardState changes (and a lot will changes on there).

Any ideas? I've looked but haven't been able to find a pipeable operator to put inbetween the select and tap, which will then only proceed to tap if a certain condition, i.e. dashboardState.issuesState.issues having a value, is met.


Solution

  • Here is a solution that utilizes the filter operator:

    this.store.pipe(
      select((state: AppState) => state.dashboard),
      filter((dashboardState: State) => dashboardState.issuesState.issues && dashboardState.defaultAssetId),
      tap((dashboardState: State) => this.setCurrentlySelectedAsset(dashboardState.defaultAssetId))
    ).subscribe();
    

    If the predicate returns true, then the value will be emitted to tap, otherwise, it will not be emitted.