Skip to content

Commit

Permalink
feat(store): add object-style StoreModule.forFeature overload (#2821)
Browse files Browse the repository at this point in the history
Closes #2809
  • Loading branch information
lacolaco authored Dec 16, 2020
1 parent 7f4e5ef commit 17571e5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
30 changes: 30 additions & 0 deletions modules/store/spec/modules.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,34 @@ describe(`Store Modules`, () => {
});
});
});

describe(`: With slice object`, () => {
@NgModule({
imports: [
StoreModule.forFeature({ name: 'a', reducer: featureAReducer }),
],
})
class FeatureAModule {}

@NgModule({
imports: [StoreModule.forRoot({}), FeatureAModule],
})
class RootModule {}

beforeEach(() => {
TestBed.configureTestingModule({
imports: [RootModule],
});

store = TestBed.inject(Store);
});

it('should set up a feature state', () => {
store.pipe(take(1)).subscribe((state: State) => {
expect(state).toEqual({
a: 5,
} as State);
});
});
});
});
1 change: 1 addition & 0 deletions modules/store/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ export {
StoreFeatureModule,
RootStoreConfig,
StoreConfig,
FeatureSlice,
} from './store_module';
export { On, on, createReducer } from './reducer_creator';
35 changes: 32 additions & 3 deletions modules/store/src/store_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ export interface RootStoreConfig<T, V extends Action = Action>
runtimeChecks?: Partial<RuntimeChecks>;
}

/**
* An object with the name and the reducer for the feature.
*/
export interface FeatureSlice<T, V extends Action = Action> {
name: string;
reducer: ActionReducer<T, V>;
}

@NgModule({})
export class StoreModule {
static forRoot<T, V extends Action = Action>(
Expand Down Expand Up @@ -192,15 +200,36 @@ export class StoreModule {
reducer: ActionReducer<T, V> | InjectionToken<ActionReducer<T, V>>,
config?: StoreConfig<T, V> | InjectionToken<StoreConfig<T, V>>
): ModuleWithProviders<StoreFeatureModule>;
static forFeature<T, V extends Action = Action>(
slice: FeatureSlice<T, V>,
config?: StoreConfig<T, V> | InjectionToken<StoreConfig<T, V>>
): ModuleWithProviders<StoreFeatureModule>;
static forFeature(
featureName: string,
reducers:
featureNameOrSlice: string | FeatureSlice<any, any>,
reducersOrConfig?:
| ActionReducerMap<any, any>
| InjectionToken<ActionReducerMap<any, any>>
| ActionReducer<any, any>
| InjectionToken<ActionReducer<any, any>>,
| InjectionToken<ActionReducer<any, any>>
| StoreConfig<any, any>
| InjectionToken<StoreConfig<any, any>>,
config: StoreConfig<any, any> | InjectionToken<StoreConfig<any, any>> = {}
): ModuleWithProviders<StoreFeatureModule> {
let featureName: string;
let reducers:
| ActionReducerMap<any, any>
| InjectionToken<ActionReducerMap<any, any>>
| ActionReducer<any, any>
| InjectionToken<ActionReducer<any, any>>;
if (typeof featureNameOrSlice === 'string') {
featureName = featureNameOrSlice;
reducers = reducersOrConfig as any;
} else {
featureName = featureNameOrSlice.name;
reducers = featureNameOrSlice.reducer;
config = (reducersOrConfig as any) ?? {};
}

return {
ngModule: StoreFeatureModule,
providers: [
Expand Down

0 comments on commit 17571e5

Please sign in to comment.