Skip to content

Commit

Permalink
feat(router-store): add routerState to action payload (#1511)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver authored and brandonroberts committed Jan 21, 2019
1 parent c8bc008 commit 283424f
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 16 deletions.
46 changes: 46 additions & 0 deletions modules/router-store/spec/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
RouterStateSnapshot,
NavigationCancel,
NavigationError,
ActivatedRouteSnapshot,
} from '@angular/router';
import { Store, ScannedActionsSubject } from '@ngrx/store';
import { filter, first, mapTo, take } from 'rxjs/operators';
Expand Down Expand Up @@ -88,6 +89,51 @@ describe('integration spec', () => {
});
});

it('should have the routerState in the payload', (done: any) => {
const actionLog: RouterAction<any>[] = [];
const reducer = (state: string = '', action: RouterAction<any>) => {
switch (action.type) {
case ROUTER_CANCEL:
case ROUTER_ERROR:
case ROUTER_NAVIGATED:
case ROUTER_NAVIGATION:
case ROUTER_REQUEST:
actionLog.push(action);
return state;
default:
return state;
}
};

createTestModule({
reducers: { reducer },
canActivate: (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) => state.url !== 'next',
});

const router: Router = TestBed.get(Router);
const log = logOfRouterAndActionsAndStore();

const hasRouterState = (action: RouterAction<any>) =>
!!action.payload.routerState;

router
.navigateByUrl('/')
.then(() => {
expect(actionLog.filter(hasRouterState).length).toBe(actionLog.length);
})
.then(() => {
actionLog.splice(0);
return router.navigateByUrl('next');
})
.then(() => {
expect(actionLog.filter(hasRouterState).length).toBe(actionLog.length);
done();
});
});

xit('should support preventing navigation', (done: any) => {
const reducer = (state: string = '', action: RouterAction<any>) => {
if (
Expand Down
40 changes: 29 additions & 11 deletions modules/router-store/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@ export const ROUTER_REQUEST = '@ngrx/router-store/request';
/**
* Payload of ROUTER_REQUEST
*/
export type RouterRequestPayload = {
export type RouterRequestPayload<
T extends BaseRouterStoreState = SerializedRouterStateSnapshot
> = {
routerState: T;
event: NavigationStart;
};

/**
* An action dispatched when a router navigation request is fired.
*/
export type RouterRequestAction = {
export type RouterRequestAction<
T extends BaseRouterStoreState = SerializedRouterStateSnapshot
> = {
type: typeof ROUTER_REQUEST;
payload: RouterRequestPayload;
payload: RouterRequestPayload<T>;
};

/**
Expand All @@ -39,7 +44,9 @@ export const ROUTER_NAVIGATION = '@ngrx/router-store/navigation';
/**
* Payload of ROUTER_NAVIGATION.
*/
export type RouterNavigationPayload<T extends BaseRouterStoreState> = {
export type RouterNavigationPayload<
T extends BaseRouterStoreState = SerializedRouterStateSnapshot
> = {
routerState: T;
event: RoutesRecognized;
};
Expand All @@ -62,7 +69,10 @@ export const ROUTER_CANCEL = '@ngrx/router-store/cancel';
/**
* Payload of ROUTER_CANCEL.
*/
export type RouterCancelPayload<T, V extends BaseRouterStoreState> = {
export type RouterCancelPayload<
T,
V extends BaseRouterStoreState = SerializedRouterStateSnapshot
> = {
routerState: V;
storeState: T;
event: NavigationCancel;
Expand All @@ -87,7 +97,10 @@ export const ROUTER_ERROR = '@ngrx/router-store/error';
/**
* Payload of ROUTER_ERROR.
*/
export type RouterErrorPayload<T, V extends BaseRouterStoreState> = {
export type RouterErrorPayload<
T,
V extends BaseRouterStoreState = SerializedRouterStateSnapshot
> = {
routerState: V;
storeState: T;
event: NavigationError;
Expand All @@ -112,16 +125,21 @@ export const ROUTER_NAVIGATED = '@ngrx/router-store/navigated';
/**
* Payload of ROUTER_NAVIGATED.
*/
export type RouterNavigatedPayload = {
export type RouterNavigatedPayload<
T extends BaseRouterStoreState = SerializedRouterStateSnapshot
> = {
routerState: T;
event: NavigationEnd;
};

/**
* An action dispatched after navigation has ended and new route is active.
*/
export type RouterNavigatedAction = {
export type RouterNavigatedAction<
T extends BaseRouterStoreState = SerializedRouterStateSnapshot
> = {
type: typeof ROUTER_NAVIGATED;
payload: RouterNavigatedPayload;
payload: RouterNavigatedPayload<T>;
};

/**
Expand All @@ -131,8 +149,8 @@ export type RouterAction<
T,
V extends BaseRouterStoreState = SerializedRouterStateSnapshot
> =
| RouterRequestAction
| RouterRequestAction<V>
| RouterNavigationAction<V>
| RouterCancelAction<T, V>
| RouterErrorAction<T, V>
| RouterNavigatedAction;
| RouterNavigatedAction<V>;
27 changes: 22 additions & 5 deletions modules/router-store/src/router_store_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
RoutesRecognized,
NavigationStart,
Event,
RouterEvent,
} from '@angular/router';
import { select, Selector, Store } from '@ngrx/store';
import { withLatestFrom } from 'rxjs/operators';
Expand Down Expand Up @@ -51,6 +52,12 @@ export interface StoreRouterConfig<
navigationActionTiming?: NavigationActionTiming;
}

interface StoreRouterActionPayload {
event: RouterEvent;
routerState?: SerializedRouterStateSnapshot;
storeState?: any;
}

export enum NavigationActionTiming {
PreActivation = 1,
PostActivation = 2,
Expand Down Expand Up @@ -281,28 +288,38 @@ export class StoreRouterConnectingModule {

private dispatchRouterCancel(event: NavigationCancel): void {
this.dispatchRouterAction(ROUTER_CANCEL, {
routerState: this.routerState!,
storeState: this.storeState,
event,
});
}

private dispatchRouterError(event: NavigationError): void {
this.dispatchRouterAction(ROUTER_ERROR, {
routerState: this.routerState!,
storeState: this.storeState,
event: new NavigationError(event.id, event.url, `${event}`),
});
}

private dispatchRouterNavigated(event: NavigationEnd): void {
this.dispatchRouterAction(ROUTER_NAVIGATED, { event });
const routerState = this.serializer.serialize(
this.router.routerState.snapshot
);
this.dispatchRouterAction(ROUTER_NAVIGATED, { event, routerState });
}

private dispatchRouterAction(type: string, payload: any): void {
private dispatchRouterAction(
type: string,
payload: StoreRouterActionPayload
): void {
this.trigger = RouterTrigger.ROUTER;
try {
this.store.dispatch({ type, payload });
this.store.dispatch({
type,
payload: {
routerState: this.routerState,
...payload,
},
});
} finally {
this.trigger = RouterTrigger.NONE;
}
Expand Down

0 comments on commit 283424f

Please sign in to comment.