Skip to content

Commit ecb6682

Browse files
committed
add functionality to ngrx router/store
1 parent 5a33ae2 commit ecb6682

File tree

6 files changed

+102
-12
lines changed

6 files changed

+102
-12
lines changed

src/app/actions/router.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Action } from '@ngrx/store';
2+
import { NavigationExtras } from '@angular/router';
3+
4+
export const GO = '[Router] Go';
5+
export const BACK = '[Router] Back';
6+
export const FORWARD = '[Router] Forward';
7+
8+
export class Go implements Action {
9+
readonly type = GO;
10+
11+
constructor(public payload: {
12+
path: any[];
13+
query?: object;
14+
extras?: NavigationExtras;
15+
}) { }
16+
}
17+
18+
export class Back implements Action {
19+
readonly type = BACK;
20+
}
21+
22+
export class Forward implements Action {
23+
readonly type = FORWARD;
24+
}
25+
26+
export type Actions
27+
= Go
28+
| Back
29+
| Forward;

src/app/app.component.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
22
import { ActivatedRoute, Router } from '@angular/router';
33
import { TransferState } from '../modules/transfer-state/transfer-state';
4+
import { Store, select } from '@ngrx/store';
45

56
import { views } from './app-nav-views';
67
import { MOBILE } from './services/constants';
78

9+
import * as fromRoot from './reducers';
10+
811
@Component({
912
selector: 'my-app',
1013
styleUrls: ['main.scss', './app.component.scss'],
@@ -22,11 +25,14 @@ export class AppComponent implements OnInit {
2225
constructor(
2326
private cache: TransferState,
2427
public route: ActivatedRoute,
25-
public router: Router
28+
public router: Router,
29+
public store: Store<fromRoot.AppState>
2630
) { }
2731

2832
ngOnInit() {
2933
this.cache.set('cached', true);
34+
let a = this.store.pipe(select(fromRoot.getUserLoaded));
35+
a.subscribe(l => console.log(l));
3036
}
3137

3238
activateEvent(event) {

src/app/app.imports.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import { TransferHttpModule } from '../modules/transfer-http/transfer-http.modul
1212

1313
import { DEV_REDUCERS, syncReducers, resetOnLogout, AppState } from './reducers';
1414
import { StoreDevToolsModule } from './features/store-devtools.module';
15+
import { RouterEffects } from './effects/router';
1516
import { UserEffects } from './user/user.effects';
1617
import { userReducer } from './user/user.reducer';
17-
import { storeFreeze } from 'ngrx-store-freeze';
1818

1919
const STORE_DEV_TOOLS_IMPORTS = [];
2020
if (ENV === 'development' && !AOT &&
@@ -32,11 +32,16 @@ export const metaReducers: MetaReducer<AppState>[] = ENV === 'development' ?
3232
[...DEV_REDUCERS, resetOnLogout] : [resetOnLogout];
3333

3434
export const APP_IMPORTS = [
35-
EffectsModule.forRoot([UserEffects]),
35+
EffectsModule.forRoot([
36+
RouterEffects,
37+
UserEffects
38+
]),
3639
MaterialModule,
3740
ReactiveFormsModule,
3841
StoreModule.forRoot(syncReducers, { metaReducers }),
39-
StoreRouterConnectingModule,
42+
StoreRouterConnectingModule.forRoot({
43+
stateKey: 'router' // name of reducer key
44+
}),
4045
STORE_DEV_TOOLS_IMPORTS,
4146
StoreDevToolsModule,
4247
TransferHttpModule

src/app/effects/router.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Injectable } from '@angular/core';
2+
import { Router } from '@angular/router';
3+
import { Location } from '@angular/common';
4+
import { Effect, Actions, ofType } from '@ngrx/effects';
5+
import { map, tap } from 'rxjs/operators';
6+
import * as RouterActions from '../actions/router';
7+
8+
@Injectable()
9+
export class RouterEffects {
10+
@Effect({ dispatch: false })
11+
navigate$ = this.actions$.pipe(
12+
ofType(RouterActions.GO),
13+
map((action: RouterActions.Go) => action.payload),
14+
// tslint:disable-next-line:max-line-length
15+
tap(({ path, query: queryParams, extras}) => this.router.navigate(path, { queryParams, ...extras }))
16+
);
17+
18+
@Effect({ dispatch: false })
19+
navigateBack$ = this.actions$.pipe(
20+
ofType(RouterActions.BACK),
21+
tap(() => this.location.back())
22+
);
23+
24+
@Effect({ dispatch: false })
25+
navigateForward$ = this.actions$.pipe(
26+
ofType(RouterActions.FORWARD),
27+
tap(() => this.location.forward())
28+
);
29+
30+
constructor(
31+
private actions$: Actions,
32+
private router: Router,
33+
private location: Location
34+
) {}
35+
}

src/app/reducers/index.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
import { StoreModule, ActionReducerMap, MetaReducer } from '@ngrx/store';
1+
import {
2+
StoreModule,
3+
ActionReducerMap,
4+
MetaReducer,
5+
createFeatureSelector,
6+
createSelector
7+
} from '@ngrx/store';
28
import { Params, RouterStateSnapshot } from '@angular/router';
39
import { compose } from '@ngrx/store';
410
import { ActionReducer, combineReducers } from '@ngrx/store';
511
import { storeFreeze } from 'ngrx-store-freeze';
612
import { storeLogger } from 'ngrx-store-logger';
713
import { routerReducer, RouterReducerState, RouterStateSerializer } from '@ngrx/router-store';
14+
import * as fromRouter from '@ngrx/router-store';
815

916
import * as fromUser from '../user/user.reducer';
1017

@@ -20,7 +27,7 @@ const modules = {
2027
};
2128

2229
export interface AppState {
23-
router: RouterReducerState<RouterStateUrl>;
30+
router: fromRouter.RouterReducerState<RouterStateUrl>;
2431
user: fromUser.UserState;
2532
}
2633

@@ -29,16 +36,22 @@ export const syncReducers = {
2936
user: fromUser.userReducer
3037
};
3138

39+
export const getUserState = createFeatureSelector<fromUser.UserState>('user');
40+
41+
export const getUserLoaded = createSelector(
42+
getUserState,
43+
fromUser.getLoaded
44+
);
45+
3246
export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> {
3347
serialize(routerState: RouterStateSnapshot): RouterStateUrl {
3448
let route = routerState.root;
3549
while (route.firstChild) {
3650
route = route.firstChild;
3751
}
3852

39-
const { url } = routerState;
40-
const queryParams = routerState.root.queryParams;
41-
const params = route.params;
53+
const { url, root: { queryParams } } = routerState;
54+
const { params } = route;
4255

4356
// Only return an object including the URL, params and query params
4457
// instead of the entire snapshot
@@ -65,7 +78,7 @@ const createReducer = (asyncReducers = {}) => {
6578

6679
// Generate a reducer to set the root state in dev mode for HMR
6780
function stateSetter(reducer: ActionReducer<any>): ActionReducer<any> {
68-
return function(state: any, action: any) {
81+
return function (state: any, action: any) {
6982
if (action.type === 'SET_ROOT_STATE') {
7083
return action.payload;
7184
}
@@ -74,15 +87,15 @@ function stateSetter(reducer: ActionReducer<any>): ActionReducer<any> {
7487
}
7588

7689
function logout(reducer: ActionReducer<AppState>): ActionReducer<AppState> {
77-
return function(state: AppState, action: any): AppState {
90+
return function (state: AppState, action: any): AppState {
7891
if (action.type === '[User] Logout Success') {
7992
state = undefined;
8093
}
8194
return reducer(state, action);
8295
};
8396
}
8497

85-
export function resetOnLogout (reducer: ActionReducer<AppState>): ActionReducer<AppState> {
98+
export function resetOnLogout(reducer: ActionReducer<AppState>): ActionReducer<AppState> {
8699
return function (state, action) {
87100
let newState;
88101
if (action.type === '[User] Logout Success') {

src/app/user/user.reducer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ export function userReducer(state = initialState, action: UserActions): UserStat
3131
}
3232
}
3333
}
34+
35+
export const getLoaded = (state: UserState) => state.loaded;

0 commit comments

Comments
 (0)