Selector Utils
Why?
Selectors are one of the most powerful features in NGXS
. When used in a correct way they are very performant due to the built-in memoization. However, in order to use selectors correctly we usually need to break down the state into smaller selectors that, in turn, will be used by other selectors. This approach is important to guarantee that selectors are only run when a change of interest has happened. The process of breaking down your state into simple selectors for each property of the state model can be tedious and usually comes with a lot of boilerplate. The objective the selector utils is to make it easy to generate these selectors, combine selectors from multiple states, and create a selector based on a subset of properties of your state.
These are the provided utils:
createPropertySelectors - create a selector for each property of an object returned by a selector.
createModelSelector - create a selector that returns an object which is composed from values returned by multiple selectors.
createPickSelector - create a selector that returns a subset of an object's properties, and changes only when those properties change.
Create Property Selectors
Let's start with a common example. Here we have a small state containing animals. Check the snippet below:
Here we see how verbose the split of a state into selectors can look. We can use the createPropertySelectors
to cleanup this code a bit. See the snippet below:
Here we see how the createPropertySelectors
is used to create a map of selectors for each property of the state. The createPropertySelectors
takes a state class and returns a map of selectors for each property of the state. The createPropertySelectors
is very useful when we need to create a selector for each property of the state.
TYPE SAFETY: Note that, in the
createPropertySelectors
call above, the model type was provided to the function as a type parameter. This was only necessary because the state class (AnimalsSate
) was provided and the class does not include model information. ThecreatePropertySelectors
function will not require a type parameter if a typed selector or aStateToken
that includes the type of the model is provided to the function.
Create Model Selector
Sometimes we need to create a selector simply groups other selectors. For example, we might want to create a selector that maps the state to a map of pandas and zoos. We can use the createModelSelector
to create such a selector. See the snippet below:
Here we see how the createModelSelector
is used to create a selector that maps the state to a map of pandas and zoos. The createModelSelector
takes a map of selectors and returns a selector that maps the state to a map of the values returned by the selectors. The createModelSelector
is very useful when we need to create a selector that groups other selectors.
TYPE SAFETY: Note that it is always best to use typed selectors in the selector map provided to the
createModelSelector
function. The output model is inferred from the selector map. A state class (eg.AnimalSate
) does not include model information and this causes issues with the type inference. It is also questionable why an entire state would be included in a model, because this breaks encapsulation and would also cause change detection to trigger more often.
Create Pick Selector
Sometimes we need to create a selector that picks a subset of properties from the state. For example, we might want to create a selector that picks only the zebras
and pandas
properties from the state. We can use the createPickSelector
to create such a selector. See the snippet below:
The zebrasAndPandas
object above would only contain the zebras
and pandas
properties, and not have the monkeys
property.
Here we see how the createPickSelector
is used to create a selector that picks a subset of properties from the state, or from any other selector that returns an object for that matter. The createPickSelector
takes a selector which returns an object and an array of property names and returns a selector that returns a copy of the object, with only the properties that have been picked. The createPickSelector
is very useful when we need to create a selector that picks a subset of properties from the state.
TYPE SAFETY: The
createPickSelector
function should only be provided a strongly typed selector or aStateToken
that includes the type of the model. This is so that type safety is maintained for the picked properties.
Noteable Performance win!
One of the most useful things about the createPickSelector
selector (versus rolling your own that creates a trimmed object from the provided selector), is that it will only emit a new value when a picked property changes, and will not emit a new value if any of the other properties change. An Angular change detection performance enthusiasts dream!
Last updated