From 6da3ec50478a9659bd68e7d996eaef8390f1ce4e Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 17 Aug 2017 18:31:13 -0500 Subject: [PATCH] fix(RouterStore): Add generic type to RouterReducerState (#292) Closes #289 --- docs/router-store/api.md | 22 +++++++++--- example-app/app/reducers/index.ts | 3 +- example-app/app/shared/utils.ts | 10 +++--- modules/router-store/spec/integration.spec.ts | 15 ++++++-- .../router-store/src/router_store_module.ts | 34 +++++++++---------- 5 files changed, 54 insertions(+), 30 deletions(-) diff --git a/docs/router-store/api.md b/docs/router-store/api.md index b9eca6d52e..052b9b58f3 100644 --- a/docs/router-store/api.md +++ b/docs/router-store/api.md @@ -8,31 +8,43 @@ issues when used with the Store Devtools. In most cases, you may only need a pie To use the time-traveling debugging in the Devtools, you must return an object containing the `url` when using the `routerReducer`. ```ts -import { StoreModule } from '@ngrx/store'; +import { StoreModule, ActionReducerMap } from '@ngrx/store'; +import { Params } from '@angular/router'; import { StoreRouterConnectingModule, routerReducer, + RouterReducerState, RouterStateSerializer, - RouterStateSnapshotType + RouterStateSnapshot } from '@ngrx/router-store'; export interface RouterStateUrl { url: string; + queryParams: Params; +} + +export interface State { + routerReducer: RouterReducerState; } export class CustomSerializer implements RouterStateSerializer { serialize(routerState: RouterStateSnapshot): RouterStateUrl { const { url } = routerState; + const queryParams = routerState.root.queryParams; - // Only return an object including the URL + // Only return an object including the URL and query params // instead of the entire snapshot - return { url }; + return { url, queryParams }; } } +export const reducers: ActionReducerMap = { + routerReducer: routerReducer +}; + @NgModule({ imports: [ - StoreModule.forRoot({ routerReducer: routerReducer }), + StoreModule.forRoot(reducers), RouterModule.forRoot([ // routes ]), diff --git a/example-app/app/reducers/index.ts b/example-app/app/reducers/index.ts index cb26504f4a..86b13db736 100644 --- a/example-app/app/reducers/index.ts +++ b/example-app/app/reducers/index.ts @@ -6,6 +6,7 @@ import { MetaReducer, } from '@ngrx/store'; import { environment } from '../../environments/environment'; +import { RouterStateUrl } from '../shared/utils'; import * as fromRouter from '@ngrx/router-store'; /** @@ -23,7 +24,7 @@ import * as fromLayout from '../core/reducers/layout'; */ export interface State { layout: fromLayout.State; - routerReducer: fromRouter.RouterReducerState; + routerReducer: fromRouter.RouterReducerState; } /** diff --git a/example-app/app/shared/utils.ts b/example-app/app/shared/utils.ts index 758011bce2..c292c84780 100644 --- a/example-app/app/shared/utils.ts +++ b/example-app/app/shared/utils.ts @@ -1,24 +1,26 @@ import { RouterStateSerializer } from '@ngrx/router-store'; -import { RouterStateSnapshot } from '@angular/router'; +import { RouterStateSnapshot, Params } from '@angular/router'; /** * The RouterStateSerializer takes the current RouterStateSnapshot * and returns any pertinent information needed. The snapshot contains * all information about the state of the router at the given point in time. * The entire snapshot is complex and not always needed. In this case, you only - * need the URL from the snapshot in the store. Other items could be - * returned such as route parameters, query parameters and static route data. + * need the URL and query parameters from the snapshot in the store. Other items could be + * returned such as route parameters and static route data. */ export interface RouterStateUrl { url: string; + queryParams: Params; } export class CustomRouterStateSerializer implements RouterStateSerializer { serialize(routerState: RouterStateSnapshot): RouterStateUrl { const { url } = routerState; + const queryParams = routerState.root.queryParams; - return { url }; + return { url, queryParams }; } } diff --git a/modules/router-store/spec/integration.spec.ts b/modules/router-store/spec/integration.spec.ts index c0c53184a0..4af94dff08 100644 --- a/modules/router-store/spec/integration.spec.ts +++ b/modules/router-store/spec/integration.spec.ts @@ -325,11 +325,13 @@ describe('integration spec', () => { : null; }; - class CustomSerializer implements RouterStateSerializer<{ url: string }> { + class CustomSerializer + implements RouterStateSerializer<{ url: string; params: any }> { serialize(routerState: RouterStateSnapshot) { const url = `${routerState.url}-custom`; + const params = { test: 1 }; - return { url }; + return { url, params }; } } @@ -353,7 +355,14 @@ describe('integration spec', () => { expect(log).toEqual([ { type: 'router', event: 'NavigationStart', url: '/next' }, { type: 'router', event: 'RoutesRecognized', url: '/next' }, - { type: 'store', state: { url: '/next-custom', navigationId: 2 } }, + { + type: 'store', + state: { + url: '/next-custom', + navigationId: 2, + params: { test: 1 }, + }, + }, { type: 'router', event: 'NavigationEnd', url: '/next' }, ]); log.splice(0); diff --git a/modules/router-store/src/router_store_module.ts b/modules/router-store/src/router_store_module.ts index 424f6b275d..cbf111c2be 100644 --- a/modules/router-store/src/router_store_module.ts +++ b/modules/router-store/src/router_store_module.ts @@ -28,7 +28,7 @@ export type RouterNavigationPayload = { /** * An action dispatched when the router navigates. */ -export type RouterNavigationAction = { +export type RouterNavigationAction = { type: typeof ROUTER_NAVIGATION; payload: RouterNavigationPayload; }; @@ -41,8 +41,8 @@ export const ROUTER_CANCEL = 'ROUTER_CANCEL'; /** * Payload of ROUTER_CANCEL. */ -export type RouterCancelPayload = { - routerState: RouterStateSnapshot; +export type RouterCancelPayload = { + routerState: V; storeState: T; event: NavigationCancel; }; @@ -50,9 +50,9 @@ export type RouterCancelPayload = { /** * An action dispatched when the router cancel navigation. */ -export type RouterCancelAction = { +export type RouterCancelAction = { type: typeof ROUTER_CANCEL; - payload: RouterCancelPayload; + payload: RouterCancelPayload; }; /** @@ -63,8 +63,8 @@ export const ROUTER_ERROR = 'ROUTE_ERROR'; /** * Payload of ROUTER_ERROR. */ -export type RouterErrorPayload = { - routerState: RouterStateSnapshot; +export type RouterErrorPayload = { + routerState: V; storeState: T; event: NavigationError; }; @@ -72,28 +72,28 @@ export type RouterErrorPayload = { /** * An action dispatched when the router errors. */ -export type RouterErrorAction = { +export type RouterErrorAction = { type: typeof ROUTER_ERROR; - payload: RouterErrorPayload; + payload: RouterErrorPayload; }; /** * An union type of router actions. */ -export type RouterAction = +export type RouterAction = | RouterNavigationAction - | RouterCancelAction - | RouterErrorAction; + | RouterCancelAction + | RouterErrorAction; -export type RouterReducerState = { - state: RouterStateSnapshot; +export type RouterReducerState = { + state: T; navigationId: number; }; -export function routerReducer( - state: RouterReducerState, +export function routerReducer( + state: RouterReducerState, action: RouterAction -): RouterReducerState { +): RouterReducerState { switch (action.type) { case ROUTER_NAVIGATION: case ROUTER_ERROR: