-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CreateSelectorFactory returns entire state when provided an empty array of selectors #1501
Comments
I think that the current implementation is correct, but also that the previous implementation was correct. The reasoning behind it is the following:
The change that causes this: These changes maked the following possible: const getTodosById = createSelector(
(state: TodoAppSchema, id: number) => state.todos.find(p => p.id === id)
); Instead of the need to create a selector/getter: const getTodosById = createSelector(
(state: TodoAppSchema) => state,
(todos: Todo[], id: number) => todos.find(p => p.id === id)
); To end, I think you made a selector with only a projection function which isn't possible if you would try this to do this in a "typed" way e.g. In order to "fix" this: a) we can remove the props selector with only a projection function, thus also the extra check const selector = createSelector(x => x)
xxx(47) // gives the error 'Expected 2 arguments, but got 1.'
xxx(47, props) // is OK // proposed fix
if (selectors.length === 0 && props !== undefined) {
return projector.apply(null, [state, props]);
} Personally, I think we should leave it as it is, but I'm more than happy to discuss it further. Meanwhile, to get your existing code to work you could use: const selectStatuses = (ids: any[]) => {
const selectors = ids.map((id) => getStatus(id) );
return createSelectorFactory(defaultMemoize)(
...(selectors.length ? selectors : [() => []]),
(statuses) => {
return statuses;
}
);
} |
Thank you for your response and solution, the guard works for what I need. Interesting, makes sense. It begs the question should the user have to guard against 'empty selectors' or should the projector function even be called if there are no props as you proposed above? I'm all for type safety; however, I feel at this point it is almost tribal knowledge that the projector function will be called with different types if the selectors provided are empty. ie const selectors = [];
createSelectorFactory(
...selectors,
(...selectorResults) => selectorResults // [{...state}, null]
vs
const selecotrs = [getAStatus, getBStatus];
createSelectorFactory(
...selectors,
(...selectorResults) => selectorResults // [aStatus, bStatus] One other note is with the workaround I need to provide the initial state for the empty selector case. const selectIsAnyUserOnline = (userIDs) => {
const selectors = userIDs.map( uid => selectIsUserOnline(uid) );
createSelectorFactory(
...(selectors .length ? selectors : [() => false]),
(...usersOnline) => usersOnline.some( isOnline => isOnline)
} I can't think of this being detrimental, but just something to think about when using this approach. |
Explanation
Providing createSelectorFactory n selectors yields inconsistent results between v6 and v7.
In version 6 if createSelectorFactory was provided an array of empty selectors, the projectorFunction would be supplied an empty array.
In version 7 the projectorFunction is supplied an array of the entire state.
Minimal reproduction of the bug/regression with instructions:
Refer to console in each stackblitz
v6
https://stackblitz.com/edit/typescript-createselectorfactory-v6
v7
https://stackblitz.com/edit/typescript-createselectorfactory-v7
Expected behavior:
Retain functionality and return an empty array if no selectors were provided.
Is there a better way to get the result of a dynamic number of selectors?
Versions of NgRx, Angular, Node, affected browser(s) and operating system(s):
ngrx v6 -> v7
Use case:
I have x members at any time which i need to query information on and display statuses, which is why i need dynamic selectors.
The text was updated successfully, but these errors were encountered: