Last active
September 17, 2020 21:23
-
-
Save cbejensen/d2a8d928af515a258b5ec9b4d944b3c5 to your computer and use it in GitHub Desktop.
NgRx Route Param Selector Creator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Params } from '@angular/router'; | |
import { RouterReducerState } from '@ngrx/router-store'; | |
// Some example context - could be different in your app. | |
export interface CustomRouteSnapshot { | |
url: string; | |
params: Params; | |
queryParams: Params; | |
} | |
export type State = RouterReducerState<CustomRouteSnapshot>; | |
export interface RouterPartialState { | |
router: RouterReducerState<CustomRouteSnapshot>; | |
} | |
export const getRouterState = createFeatureSelector<RouterPartialState, State>('router'); | |
export const getRouteSnapshot = createSelector(getRouterState, state => state.state); | |
export const getParams = createSelector(getRouteSnapshot, state => state.params); | |
export const getParam = createSelector<RouterPartialState, string, Params, string>( | |
getParams, | |
(params, param) => params[param] | |
); | |
// End example context | |
/** | |
* Generic helper selector for retrieving an entity from an entity store when that entity's ID is a route param. | |
* | |
* For example, if the URL path is `books/abc-123-def-456` and the active route in Angular is `books/:bookId`, given | |
* the following selector: | |
* | |
* ```typescript | |
* export const getBooksState = createFeatureSelector<BooksPartialState, State>(BOOKS_FEATURE_KEY); | |
* | |
* const { selectEntities } = booksAdapter.getSelectors(); | |
* | |
* export const getBooksEntities = createSelector(getBooksState, state => selectEntities(state)); | |
* ``` | |
* | |
* You could create a selector to get the book at this route (the book with an ID of `abc-123-def-456`) like this: | |
* | |
* @example | |
* ```typescript | |
* export const getSelectedBook = createEntitySelectorFromRouteParam(getBooksEntities, 'bookId'); | |
* ``` | |
* | |
* @param getEntities A selector that returns a dictionary of entities. | |
* @param [idParam='id'] The name of the parameter that holds the ID of the entity you want. Defaults to `id`. | |
*/ | |
export const createEntitySelectorFromRouteParam = <S extends {}, D extends Dictionary<any>>( | |
getEntities: MemoizedSelector<S, D>, | |
idParam = 'id' | |
) => { | |
return createSelector<RouterPartialState & S, D, string, D[keyof D] | undefined>( | |
getEntities, | |
state => getParam(state, idParam), | |
(entities, id) => entities[id] | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment