Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(RouterStore): Add generic type to RouterReducerState #292

Merged
merged 1 commit into from
Aug 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions docs/router-store/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<RouterStateUrl>;
}

export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> {
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<State> = {
routerReducer: routerReducer
};

@NgModule({
imports: [
StoreModule.forRoot({ routerReducer: routerReducer }),
StoreModule.forRoot(reducers),
RouterModule.forRoot([
// routes
]),
Expand Down
3 changes: 2 additions & 1 deletion example-app/app/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -23,7 +24,7 @@ import * as fromLayout from '../core/reducers/layout';
*/
export interface State {
layout: fromLayout.State;
routerReducer: fromRouter.RouterReducerState;
routerReducer: fromRouter.RouterReducerState<RouterStateUrl>;
}

/**
Expand Down
10 changes: 6 additions & 4 deletions example-app/app/shared/utils.ts
Original file line number Diff line number Diff line change
@@ -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<RouterStateUrl> {
serialize(routerState: RouterStateSnapshot): RouterStateUrl {
const { url } = routerState;
const queryParams = routerState.root.queryParams;

return { url };
return { url, queryParams };
}
}
15 changes: 12 additions & 3 deletions modules/router-store/spec/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
}
}

Expand All @@ -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);
Expand Down
34 changes: 17 additions & 17 deletions modules/router-store/src/router_store_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type RouterNavigationPayload<T> = {
/**
* An action dispatched when the router navigates.
*/
export type RouterNavigationAction<T> = {
export type RouterNavigationAction<T = RouterStateSnapshot> = {
type: typeof ROUTER_NAVIGATION;
payload: RouterNavigationPayload<T>;
};
Expand All @@ -41,18 +41,18 @@ export const ROUTER_CANCEL = 'ROUTER_CANCEL';
/**
* Payload of ROUTER_CANCEL.
*/
export type RouterCancelPayload<T> = {
routerState: RouterStateSnapshot;
export type RouterCancelPayload<T, V> = {
routerState: V;
storeState: T;
event: NavigationCancel;
};

/**
* An action dispatched when the router cancel navigation.
*/
export type RouterCancelAction<T> = {
export type RouterCancelAction<T, V = RouterStateSnapshot> = {
type: typeof ROUTER_CANCEL;
payload: RouterCancelPayload<T>;
payload: RouterCancelPayload<T, V>;
};

/**
Expand All @@ -63,37 +63,37 @@ export const ROUTER_ERROR = 'ROUTE_ERROR';
/**
* Payload of ROUTER_ERROR.
*/
export type RouterErrorPayload<T> = {
routerState: RouterStateSnapshot;
export type RouterErrorPayload<T, V> = {
routerState: V;
storeState: T;
event: NavigationError;
};

/**
* An action dispatched when the router errors.
*/
export type RouterErrorAction<T> = {
export type RouterErrorAction<T, V = RouterStateSnapshot> = {
type: typeof ROUTER_ERROR;
payload: RouterErrorPayload<T>;
payload: RouterErrorPayload<T, V>;
};

/**
* An union type of router actions.
*/
export type RouterAction<T> =
export type RouterAction<T, V = RouterStateSnapshot> =
| RouterNavigationAction<T>
| RouterCancelAction<T>
| RouterErrorAction<T>;
| RouterCancelAction<T, V>
| RouterErrorAction<T, V>;

export type RouterReducerState = {
state: RouterStateSnapshot;
export type RouterReducerState<T = RouterStateSnapshot> = {
state: T;
navigationId: number;
};

export function routerReducer(
state: RouterReducerState,
export function routerReducer<T = RouterStateSnapshot>(
state: RouterReducerState<T>,
action: RouterAction<any>
): RouterReducerState {
): RouterReducerState<T> {
switch (action.type) {
case ROUTER_NAVIGATION:
case ROUTER_ERROR:
Expand Down