diff --git a/docs/store/selectors.md b/docs/store/selectors.md index 69a455017c..65e16486f1 100644 --- a/docs/store/selectors.md +++ b/docs/store/selectors.md @@ -97,13 +97,23 @@ export interface AppState { feature: FeatureState; } -export const selectFeature = createFeatureSelector('feature'); +export const selectFeature = createFeatureSelector( + 'feature' +); export const selectFeatureCount = createSelector( selectFeature, (state: FeatureState) => state.counter ); ``` +The following selector below would not compile because `foo` is not a feature slice of `AppState`. + +```ts +export const selectFeature = createFeatureSelector( + 'foo' +); +``` + ## Reset Memoized Selector The selector function returned by calling `createSelector` or `createFeatureSelector` initially has a memoized value of `null`. After a selector is invoked the first time its memoized value is stored in memory. If the selector is subsequently invoked with the same arguments it will return the memoized value. If the selector is then invoked with different arguments it will recompute and update its memoized value. Consider the following: @@ -234,9 +244,7 @@ import { filter } from 'rxjs/operators'; store .select(selectValues) - .pipe( - filter(val => val !== undefined) - ) + .pipe(filter(val => val !== undefined)) .subscribe(/* .. */); ``` @@ -247,10 +255,9 @@ The same behaviour can be achieved by re-writing the above piece of code to use ```ts import { map, filter } from 'rxjs/operators'; -store.pipe( - map(state => selectValues(state)), - filter(val => val !== undefined) -).subscribe(/* .. */); +store + .pipe(map(state => selectValues(state)), filter(val => val !== undefined)) + .subscribe(/* .. */); ``` The above can be further re-written to use the `select()` utility function from NgRx: @@ -259,10 +266,9 @@ The above can be further re-written to use the `select()` utility function from import { select } from '@ngrx/store'; import { map, filter } from 'rxjs/operators'; -store.pipe( - select(selectValues(state)), - filter(val => val !== undefined) -).subscribe(/* .. */); +store + .pipe(select(selectValues(state)), filter(val => val !== undefined)) + .subscribe(/* .. */); ``` #### Solution: Extracting a pipeable operator @@ -279,15 +285,14 @@ export const selectFilteredValues = pipe( filter(val => val !== undefined) ); -store.pipe(selectFilteredValues) - .subscribe(/* .. */); +store.pipe(selectFilteredValues).subscribe(/* .. */); ``` ### Advanced Example: Select the last {n} state transitions Let's examine the technique of combining NgRx selectors and RxJS operators in an advanced example. -In this example, we will write a selector function that projects values from two different slices of the application state. +In this example, we will write a selector function that projects values from two different slices of the application state. The projected state will emit a value when both slices of state have a value. Otherwise, the selector will emit an `undefined` value. @@ -307,7 +312,7 @@ export const selectProjectedValues = createSelector( Then, the component should visualize the history of state transitions. We are not only interested in the current state but rather like to display the last `n` pieces of state. -Meaning that we will map a stream of state values (`1`, `2`, `3`) to an array of state values (`[1, 2, 3]`). +Meaning that we will map a stream of state values (`1`, `2`, `3`) to an array of state values (`[1, 2, 3]`). ```ts // The number of state transitions is given by the user (subscriber) @@ -329,8 +334,7 @@ Finally, the component will subscribe to the store, telling the number of state ```ts // Subscribe to the store using the custom pipeable operator -store.pipe(selectLastStateTransitions(3)) - .subscribe(/* .. */); +store.pipe(selectLastStateTransitions(3)).subscribe(/* .. */); ``` See the [advanced example live in action in a Stackblitz](https://stackblitz.com/edit/angular-ngrx-effects-1rj88y?file=app%2Fstore%2Ffoo.ts) diff --git a/example-app/app/auth/reducers/index.ts b/example-app/app/auth/reducers/index.ts index 097369aaeb..38a413a500 100644 --- a/example-app/app/auth/reducers/index.ts +++ b/example-app/app/auth/reducers/index.ts @@ -21,7 +21,7 @@ export const reducers: ActionReducerMap = { loginPage: fromLoginPage.reducer, }; -export const selectAuthState = createFeatureSelector('auth'); +export const selectAuthState = createFeatureSelector('auth'); export const selectAuthStatusState = createSelector( selectAuthState, diff --git a/example-app/app/books/reducers/index.ts b/example-app/app/books/reducers/index.ts index 923de16ba7..2bebda239f 100644 --- a/example-app/app/books/reducers/index.ts +++ b/example-app/app/books/reducers/index.ts @@ -44,7 +44,7 @@ export const reducers: ActionReducerMap = { * The createFeatureSelector function selects a piece of state from the root of the state object. * This is used for selecting feature states that are loaded eagerly or lazily. */ -export const getBooksState = createFeatureSelector('books'); +export const getBooksState = createFeatureSelector('books'); /** * Every reducer module exports selector functions, however child reducers diff --git a/example-app/app/reducers/index.ts b/example-app/app/reducers/index.ts index 63a4346977..99eb5c2732 100644 --- a/example-app/app/reducers/index.ts +++ b/example-app/app/reducers/index.ts @@ -65,7 +65,9 @@ export const metaReducers: MetaReducer[] = !environment.production /** * Layout Reducers */ -export const getLayoutState = createFeatureSelector('layout'); +export const getLayoutState = createFeatureSelector( + 'layout' +); export const getShowSidenav = createSelector( getLayoutState, diff --git a/modules/store/src/selector.ts b/modules/store/src/selector.ts index f08a562e74..1acafe52e6 100644 --- a/modules/store/src/selector.ts +++ b/modules/store/src/selector.ts @@ -269,7 +269,13 @@ export function createSelectorFactory( export function createFeatureSelector( featureName: string -): MemoizedSelector { +): MemoizedSelector; +export function createFeatureSelector( + featureName: keyof T +): MemoizedSelector; +export function createFeatureSelector( + featureName: any +): MemoizedSelector { return createSelector( (state: any) => state[featureName], (featureState: any) => featureState