[Fixed] NgRx RxJS Extract and reuse common selector

Issue

I’m trying to find a way to reuse RxJS Observable that combines multiple feature selectors:

// auth.selectors.ts
export const selectAuthState
  = createFeatureSelector<AuthState>('auth');

export const selectCurrentUser = createSelector(
  selectAuthState,
  (state) => {
    return state.auth
  }
)

// foo.selectors.ts
export const selectFoosState
  = createFeatureSelector<FoosState>('foo');

export const selectAllFoos = createSelector(
  selectFoosState,
  selectAll
)

// foo.component.ts
class FooComponent {
  constructor(private store: Store) {
    this.currentUser$ = this.store.pipe(select(selectCurrentUser));
    this.availableFoos$ = this.store.pipe(select(selectAllFoos));

    // GOAL is to reuse this observable in multiple components
    this.accountIsPendingReviewMsg$ = combineLatest(
      this.currentUser$,
      this.availableFoos$
    ).pipe(
      map(([user, foos]) => {
        return user && user.role === 'user' && foos.length === 0
      })
    )
  }
}

Is it possible? Not sure how to inject that this.store in extracted function.

I would like to know if it is possible to be done using just NgRx+RxJs, probably some idiomatic solution for what seems to be a pretty common task.
Alternative solution might involve the use of decorators and Angular injector but I would like to avoid it if possible.

Solution

you can simply create a combined selector on top of the two available selectors, something like below and use "accountPendingSelector" selector everwhere.

    // auth.selectors.ts
export const selectAuthState
  = createFeatureSelector<AuthState>('auth');

export const selectCurrentUser = createSelector(
  selectAuthState,
  (state) => state.AuthState
)

// foo.selectors.ts
export const selectFoosState
  = createFeatureSelector<FoosState>('foo');

export const selectAllFoos = createSelector(
  selectFoosState,
  selectAll
);


export const accountPendingSelector = createSelector(selectCurrentUser, selectAllFoos, (user, foos) => {
  return user && user.role === 'user' && foos.length === 0;
});

Leave a Reply

(*) Required, Your email will not be published