Skip to content

Instantly share code, notes, and snippets.

@cbejensen
Last active September 17, 2020 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbejensen/d2a8d928af515a258b5ec9b4d944b3c5 to your computer and use it in GitHub Desktop.
Save cbejensen/d2a8d928af515a258b5ec9b4d944b3c5 to your computer and use it in GitHub Desktop.
NgRx Route Param Selector Creator
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