Skip to content

Commit

Permalink
feat(router-store): config option to dispatch ROUTER_NAVIGATION later
Browse files Browse the repository at this point in the history
Part of #1263
  • Loading branch information
dummdidumm authored and brandonroberts committed Aug 24, 2018
1 parent 5c814a9 commit fe71ffb
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
38 changes: 38 additions & 0 deletions modules/router-store/spec/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,44 @@ describe('integration spec', () => {
done();
});
});

it('should dispatch ROUTER_NAVIGATION later when config options set to true', () => {
const reducer = (state: string = '', action: RouterAction<any>) => {
if (action.type === ROUTER_NAVIGATION) {
return action.payload.routerState.url.toString();
} else {
return state;
}
};

createTestModule({
reducers: { reducer },
config: { dispatchNavActionOnEnd: true },
});

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

router.navigateByUrl('/').then(() => {
expect(log).toEqual([
{ type: 'store', state: '' }, // init event. has nothing to do with the router
{ type: 'store', state: '' }, // ROUTER_REQUEST event in the store
{ type: 'action', action: ROUTER_REQUEST },
{ type: 'router', event: 'NavigationStart', url: '/' },
{ type: 'router', event: 'RoutesRecognized', url: '/' },
/* new Router Lifecycle in Angular 4.3 */
{ type: 'router', event: 'GuardsCheckStart', url: '/' },
{ type: 'router', event: 'GuardsCheckEnd', url: '/' },
{ type: 'router', event: 'ResolveStart', url: '/' },
{ type: 'router', event: 'ResolveEnd', url: '/' },
{ type: 'store', state: '/' }, // ROUTER_NAVIGATION event in the store
{ type: 'action', action: ROUTER_NAVIGATION },
{ type: 'store', state: '/' }, // ROUTER_NAVIGATED event in the store
{ type: 'action', action: ROUTER_NAVIGATED },
{ type: 'router', event: 'NavigationEnd', url: '/' },
]);
});
});
});

function createTestModule(
Expand Down
17 changes: 16 additions & 1 deletion modules/router-store/src/router_store_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ export function routerReducer<
export interface StoreRouterConfig {
stateKey?: string;
serializer?: new () => RouterStateSerializer;
/**
* By default, ROUTER_NAVIGATION is dispatched before guards and resolvers run.
* Therefore, the action could run too soon, for example
* there may be a navigation cancel due to a guard saying the navigation is not allowed.
* To run ROUTER_NAVIGATION after guards and resolvers, set this property to true.
*/
dispatchNavActionOnEnd?: boolean;
}

export const _ROUTER_CONFIG = new InjectionToken(
Expand All @@ -200,6 +207,7 @@ export function _createRouterConfig(
return {
stateKey: DEFAULT_ROUTER_FEATURENAME,
serializer: DefaultRouterStateSerializer,
dispatchNavActionOnEnd: false,
..._config,
};
}
Expand Down Expand Up @@ -342,15 +350,19 @@ export class StoreRouterConnectingModule {
}

private setUpRouterEventsListener(): void {
const dispatchNavLate = this.config.dispatchNavActionOnEnd;
let routesRecognized: RoutesRecognized;

this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
if (this.trigger !== RouterTrigger.STORE) {
this.dispatchRouterRequest(event);
}
} else if (event instanceof RoutesRecognized) {
routesRecognized = event;
this.routerState = this.serializer.serialize(event.state);

if (this.trigger !== RouterTrigger.STORE) {
if (!dispatchNavLate && this.trigger !== RouterTrigger.STORE) {
this.dispatchRouterNavigation(event);
}
} else if (event instanceof NavigationCancel) {
Expand All @@ -359,6 +371,9 @@ export class StoreRouterConnectingModule {
this.dispatchRouterError(event);
} else if (event instanceof NavigationEnd) {
if (this.trigger !== RouterTrigger.STORE) {
if (dispatchNavLate) {
this.dispatchRouterNavigation(routesRecognized);
}
this.dispatchRouterNavigated(event);
}
this.trigger = RouterTrigger.NONE;
Expand Down

0 comments on commit fe71ffb

Please sign in to comment.