Skip to content

Commit 1454620

Browse files
brandonrobertsMikeRyanDev
authored andcommitted
fix(Store): Compose provided metareducers for a feature reducer (#704)
Closes #701
1 parent b9f6442 commit 1454620

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

modules/store/spec/utils.spec.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { omit } from '../src/utils';
1+
import { omit, createFeatureReducer } from '../src/utils';
22
import { combineReducers, compose } from '@ngrx/store';
33

44
describe(`Store utils`, () => {
@@ -60,7 +60,7 @@ describe(`Store utils`, () => {
6060
const precision = (n: number) => parseFloat(n.toPrecision(12));
6161
const addPtTwo = (n: number) => n + 0.2;
6262

63-
it(`should should compose functions`, () => {
63+
it(`should compose functions`, () => {
6464
const addPrecision = compose(precision, addPtTwo);
6565
const addPrecisionCubed = compose(cube, addPrecision);
6666

@@ -73,4 +73,21 @@ describe(`Store utils`, () => {
7373
expect(id(1)).toBe(1);
7474
});
7575
});
76+
77+
describe('createFeatureReducer()', () => {
78+
it('should compose a reducer from the provided meta reducers', () => {
79+
const metaReducer = jasmine
80+
.createSpy('metaReducer')
81+
.and.callFake(red => (s: any, a: any) => red(s, a));
82+
const reducer = (state: any, action: any) => state;
83+
84+
const featureReducer = createFeatureReducer(reducer, [metaReducer]);
85+
86+
const initialState = 1;
87+
const state = featureReducer(initialState, undefined);
88+
89+
expect(metaReducer).toHaveBeenCalled();
90+
expect(state).toBe(initialState);
91+
});
92+
});
7693
});

modules/store/src/reducer_manager.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import {
66
ActionReducer,
77
ActionReducerMap,
88
ActionReducerFactory,
9+
MetaReducer,
910
StoreFeature,
1011
} from './models';
1112
import { INITIAL_STATE, INITIAL_REDUCERS, REDUCER_FACTORY } from './tokens';
12-
import { omit, createReducerFactory } from './utils';
13+
import { omit, createReducerFactory, createFeatureReducer } from './utils';
1314
import { ActionsSubject } from './actions_subject';
1415

1516
export abstract class ReducerObservable extends Observable<
@@ -40,7 +41,11 @@ export class ReducerManager extends BehaviorSubject<ActionReducer<any, any>>
4041
}: StoreFeature<any, any>) {
4142
const reducer =
4243
typeof reducers === 'function'
43-
? (state: any, action: any) => reducers(state || initialState, action)
44+
? (state: any, action: any) =>
45+
createFeatureReducer(reducers, metaReducers)(
46+
state || initialState,
47+
action
48+
)
4449
: createReducerFactory(reducerFactory, metaReducers)(
4550
reducers,
4651
initialState

modules/store/src/utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,14 @@ export function createReducerFactory<T, V extends Action = Action>(
9696

9797
return reducerFactory;
9898
}
99+
100+
export function createFeatureReducer<T, V extends Action = Action>(
101+
reducer: ActionReducer<T, V>,
102+
metaReducers?: MetaReducer<T, V>[]
103+
): ActionReducer<T, V> {
104+
if (Array.isArray(metaReducers) && metaReducers.length > 0) {
105+
return compose<ActionReducer<T, V>>(...metaReducers)(reducer);
106+
}
107+
108+
return reducer;
109+
}

0 commit comments

Comments
 (0)