I have a large project that's slowly migrating to the new ngrx
syntax. We have many selectors that are plain functions like this:
export function appDetailsSelector(state$: Observable<AppState>): Observable<AppDetails> {
return state$.pipe(map((appState: AppState) => appState.appDetails));
}
New selectors are written using createSelector
:
export const selectUserConfig: MemoizedSelector<AppState, UserConfig> = createSelector(
selectUserData,
(userData: UserData) => userData.config,
);
Both of these use the same state shape, but how do I combine to create a new selector combining both of these with createSelector
?
I know I can use piping to do this in the component code:
combineLatest([
this.store.pipe(appDetailsSelector),
this.store.select(selectUserConfig),
], (appDetails, userConfig) => ...projector fn code...);
But this isn't reusable and I need it done with createSelector
to avoid repeating this in multiple components. If appDetailsSelector
was created with createSelector
it would look like this:
export const getUserBookmarks = createSelector(
appDetailsSelector,
selectUserConfig,
(appDetails: AppDetails, userConfig: UserConfig) => appDetails.useBookmarks ? userConfig.bookmarks : []
);
But this Argument of type 'MemoizedSelector<AppState, UserConfig, DefaultProjectorFn<UserConfig>>' is not assignable to parameter of type 'SelectorWithProps<Observable<AppState>, unknown, UserConfig>'. Types of parameters 'state' and 'state' are incompatible. Type 'Observable<AppState>' is missing the following properties from type 'AppState'...
I can see that the old style selectors take Observable<AppState>
and the new ones assume AppState
; how to bridge this gap and combine these two selectors?