Skip to content

Commit

Permalink
#410 Creation of StoreRouterConnectingModule.forRoot with configurati…
Browse files Browse the repository at this point in the history
…on options
  • Loading branch information
phillipzada committed Sep 21, 2017
1 parent 86caaee commit 4583010
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 9 deletions.
49 changes: 48 additions & 1 deletion modules/router-store/spec/integration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { StoreRouterConfig } from '../src/router_store_module';
import { Component, Provider } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { NavigationEnd, Router, RouterStateSnapshot } from '@angular/router';
Expand Down Expand Up @@ -411,6 +412,51 @@ describe('integration spec', () => {
done();
});
});

it('should work when defining state key', (done: any) => {
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: { stateKey: 'router-reducer' },
});

const router: Router = TestBed.get(Router);
const store = TestBed.get(Store);
const log = logOfRouterAndStore(router, store);

router
.navigateByUrl('/')
.then(() => {
expect(log).toEqual([
{ type: 'store', state: '' }, // init event. has nothing to do with the router
{ type: 'router', event: 'NavigationStart', url: '/' },
{ type: 'router', event: 'RoutesRecognized', url: '/' },
{ type: 'store', state: '/' }, // ROUTER_NAVIGATION event in the store
{ type: 'router', event: 'NavigationEnd', url: '/' },
]);
})
.then(() => {
log.splice(0);
return router.navigateByUrl('next');
})
.then(() => {
expect(log).toEqual([
{ type: 'router', event: 'NavigationStart', url: '/next' },
{ type: 'router', event: 'RoutesRecognized', url: '/next' },
{ type: 'store', state: '/next' },
{ type: 'router', event: 'NavigationEnd', url: '/next' },
]);

done();
});
});
});

function createTestModule(
Expand All @@ -419,6 +465,7 @@ function createTestModule(
canActivate?: Function;
canLoad?: Function;
providers?: Provider[];
config?: StoreRouterConfig;
} = {}
) {
@Component({
Expand Down Expand Up @@ -450,7 +497,7 @@ function createTestModule(
canLoad: ['CanLoadNext'],
},
]),
StoreRouterConnectingModule,
StoreRouterConnectingModule.forRoot(opts.config),
],
providers: [
{
Expand Down
39 changes: 31 additions & 8 deletions modules/router-store/src/router_store_module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { NgModule } from '@angular/core';
import {
NgModule,
ModuleWithProviders,
InjectionToken,
Inject,
} from '@angular/core';
import {
NavigationCancel,
NavigationError,
Expand Down Expand Up @@ -107,6 +112,11 @@ export function routerReducer<T = RouterStateSnapshot>(
}
}

export interface StoreRouterConfig {
stateKey?: string;
}
export const _ROUTER_CONFIG = new InjectionToken('@ngrx/router Configuration');

/**
* Connects RouterModule with StoreModule.
*
Expand Down Expand Up @@ -155,18 +165,31 @@ export function routerReducer<T = RouterStateSnapshot>(
],
})
export class StoreRouterConnectingModule {
static forRoot(config?: StoreRouterConfig): ModuleWithProviders;
static forRoot(config: StoreRouterConfig = {}): ModuleWithProviders {
return {
ngModule: StoreRouterConnectingModule,
providers: [{ provide: _ROUTER_CONFIG, useValue: config }],
};
}

private routerState: RouterStateSnapshot;
private storeState: any;
private lastRoutesRecognized: RoutesRecognized;

private dispatchTriggeredByRouter: boolean = false; // used only in dev mode in combination with routerReducer
private navigationTriggeredByDispatch: boolean = false; // used only in dev mode in combination with routerReducer

private stateKey: string = 'routerReducer';

constructor(
private store: Store<any>,
private router: Router,
private serializer: RouterStateSerializer<RouterStateSnapshot>
private serializer: RouterStateSerializer<RouterStateSnapshot>,
@Inject(_ROUTER_CONFIG) private config: StoreRouterConfig
) {
this.stateKey = (config && config.stateKey) || this.stateKey;

this.setUpBeforePreactivationHook();
this.setUpStoreStateListener();
this.setUpStateRollbackEvents();
Expand All @@ -187,28 +210,28 @@ export class StoreRouterConnectingModule {
this.store.subscribe(s => {
this.storeState = s;
});
this.store.select('routerReducer').subscribe(() => {
this.store.select(this.stateKey).subscribe(() => {
this.navigateIfNeeded();
});
}

private shouldDispatchRouterNavigation(): boolean {
if (!this.storeState['routerReducer']) return true;
if (!this.storeState[this.stateKey]) return true;
return !this.navigationTriggeredByDispatch;
}

private navigateIfNeeded(): void {
if (
!this.storeState['routerReducer'] ||
!this.storeState['routerReducer'].state
!this.storeState[this.stateKey] ||
!this.storeState[this.stateKey].state
) {
return;
}
if (this.dispatchTriggeredByRouter) return;

if (this.router.url !== this.storeState['routerReducer'].state.url) {
if (this.router.url !== this.storeState[this.stateKey].state.url) {
this.navigationTriggeredByDispatch = true;
this.router.navigateByUrl(this.storeState['routerReducer'].state.url);
this.router.navigateByUrl(this.storeState[this.stateKey].state.url);
}
}

Expand Down

0 comments on commit 4583010

Please sign in to comment.