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;
});