Skip to content

Commit

Permalink
fix(Store): Compose provided metareducers for a feature state
Browse files Browse the repository at this point in the history
Closes #701
  • Loading branch information
brandonroberts committed Jan 7, 2018
1 parent b9f6442 commit e7984d8
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
21 changes: 19 additions & 2 deletions modules/store/spec/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { omit } from '../src/utils';
import { omit, createFeatureReducer } from '../src/utils';
import { combineReducers, compose } from '@ngrx/store';

describe(`Store utils`, () => {
Expand Down Expand Up @@ -60,7 +60,7 @@ describe(`Store utils`, () => {
const precision = (n: number) => parseFloat(n.toPrecision(12));
const addPtTwo = (n: number) => n + 0.2;

it(`should should compose functions`, () => {
it(`should compose functions`, () => {
const addPrecision = compose(precision, addPtTwo);
const addPrecisionCubed = compose(cube, addPrecision);

Expand All @@ -73,4 +73,21 @@ describe(`Store utils`, () => {
expect(id(1)).toBe(1);
});
});

describe('createFeatureReducer()', () => {
it('should compose a reducer from the provided meta reducers', () => {
const metaReducer = jasmine
.createSpy('metaReducer')
.and.callFake(red => (s: any, a: any) => red(s, a));
const reducer = (state: any, action: any) => state;

const featureReducer = createFeatureReducer(reducer, [metaReducer]);

const initialState = 1;
const state = featureReducer(initialState, undefined);

expect(metaReducer).toHaveBeenCalled();
expect(state).toBe(initialState);
});
});
});
9 changes: 7 additions & 2 deletions modules/store/src/reducer_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
ActionReducer,
ActionReducerMap,
ActionReducerFactory,
MetaReducer,
StoreFeature,
} from './models';
import { INITIAL_STATE, INITIAL_REDUCERS, REDUCER_FACTORY } from './tokens';
import { omit, createReducerFactory } from './utils';
import { omit, createReducerFactory, createFeatureReducer } from './utils';
import { ActionsSubject } from './actions_subject';

export abstract class ReducerObservable extends Observable<
Expand Down Expand Up @@ -40,7 +41,11 @@ export class ReducerManager extends BehaviorSubject<ActionReducer<any, any>>
}: StoreFeature<any, any>) {
const reducer =
typeof reducers === 'function'
? (state: any, action: any) => reducers(state || initialState, action)
? (state: any, action: any) =>
createFeatureReducer(reducers, metaReducers)(
state || initialState,
action
)
: createReducerFactory(reducerFactory, metaReducers)(
reducers,
initialState
Expand Down
11 changes: 11 additions & 0 deletions modules/store/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,14 @@ export function createReducerFactory<T, V extends Action = Action>(

return reducerFactory;
}

export function createFeatureReducer<T, V extends Action = Action>(
reducer: ActionReducer<T, V>,
metaReducers?: MetaReducer<T, V>[]
): ActionReducer<T, V> {
if (Array.isArray(metaReducers) && metaReducers.length > 0) {
return compose<ActionReducer<T, V>>(...metaReducers)(reducer);
}

return reducer;
}

0 comments on commit e7984d8

Please sign in to comment.