I managed to provide parameters to the selector with a slight change on how I use it. Example:
selector (I do not use a separate feature here)
export const selectReferentialsState = (state: AppState) => state.referentials;
export const referentialDataSelector = createSelector(
selectReferentialsState,
(state: ReferentialsState, props: { refType: Referential}) => state.data[props.refType]
);
usage
this.availableRoles$ = this.store.select(state => referentialDataSelector(state, { refType: Referential.Role}));
Advanced usage (cascade selectors with parameters)
I will provide another example to cover the more complex scenario of having to define a selector that relies on a selector that requires parameters (props
). This also includes an easier usage syntax (pipe
+ select
):
export const selectQuestionnaireTranslationInfo = createSelector(
selectQuestionnaireTranslationState,
(state: QuestionnaireTranslationState, props: { formId: number}) => state.entities[props.formId]
);
export const selectQuestionnaireLanguageProgress = createSelector(
selectQuestionnaireTranslationInfo,
(state: QuestionnaireTemplateTranslationFullInfo, props: {formId: number, langId: number }) =>
state?.languageInfo?.find(li => li.spTranslationLanguageId === props.langId)
);
export const selectQuestionnaireLanguageProgressCount = createSelector(
selectQuestionnaireLanguageProgress,
(state: QuestionnaireTemplateTranslationLanguageInfo) =>
state?.translatedResourceCount
);
Usage:
const props = { formId: this.templateId, langId: this.languageId};
this.progressCount$ = this.store.pipe(select(selectQuestionnaireLanguageProgressCount, props));`
As already noted by Ian Jamieson, props are merged and available in the selectors chain (that's why the last selector does not require to explicitly declare the props, they are "inherited").