Skip to content

Commit a9468e1

Browse files
feat(store): add object-style StoreModule.forFeature overload w/fixes (#2885)
* feat(store): add object-style StoreModule.forFeature overload (#2821) Closes #2809 * fix(store): update StoreModule to be compliant with AOT Co-authored-by: Suguru Inatomi <suguru.inatomi@gmail.com>
1 parent 2f5dcb4 commit a9468e1

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed

modules/store/spec/modules.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,34 @@ describe(`Store Modules`, () => {
216216
});
217217
});
218218
});
219+
220+
describe(`: With slice object`, () => {
221+
@NgModule({
222+
imports: [
223+
StoreModule.forFeature({ name: 'a', reducer: featureAReducer }),
224+
],
225+
})
226+
class FeatureAModule {}
227+
228+
@NgModule({
229+
imports: [StoreModule.forRoot({}), FeatureAModule],
230+
})
231+
class RootModule {}
232+
233+
beforeEach(() => {
234+
TestBed.configureTestingModule({
235+
imports: [RootModule],
236+
});
237+
238+
store = TestBed.inject(Store);
239+
});
240+
241+
it('should set up a feature state', () => {
242+
store.pipe(take(1)).subscribe((state: State) => {
243+
expect(state).toEqual({
244+
a: 5,
245+
} as State);
246+
});
247+
});
248+
});
219249
});

modules/store/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ export {
5555
StoreFeatureModule,
5656
RootStoreConfig,
5757
StoreConfig,
58+
FeatureSlice,
5859
} from './store_module';
5960
export { On, on, createReducer } from './reducer_creator';

modules/store/src/store_module.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ export interface RootStoreConfig<T, V extends Action = Action>
114114
runtimeChecks?: Partial<RuntimeChecks>;
115115
}
116116

117+
/**
118+
* An object with the name and the reducer for the feature.
119+
*/
120+
export interface FeatureSlice<T, V extends Action = Action> {
121+
name: string;
122+
reducer: ActionReducer<T, V>;
123+
}
124+
117125
@NgModule({})
118126
export class StoreModule {
119127
static forRoot<T, V extends Action = Action>(
@@ -192,13 +200,19 @@ export class StoreModule {
192200
reducer: ActionReducer<T, V> | InjectionToken<ActionReducer<T, V>>,
193201
config?: StoreConfig<T, V> | InjectionToken<StoreConfig<T, V>>
194202
): ModuleWithProviders<StoreFeatureModule>;
203+
static forFeature<T, V extends Action = Action>(
204+
slice: FeatureSlice<T, V>,
205+
config?: StoreConfig<T, V> | InjectionToken<StoreConfig<T, V>>
206+
): ModuleWithProviders<StoreFeatureModule>;
195207
static forFeature(
196-
featureName: string,
197-
reducers:
208+
featureNameOrSlice: string | FeatureSlice<any, any>,
209+
reducersOrConfig?:
198210
| ActionReducerMap<any, any>
199211
| InjectionToken<ActionReducerMap<any, any>>
200212
| ActionReducer<any, any>
201-
| InjectionToken<ActionReducer<any, any>>,
213+
| InjectionToken<ActionReducer<any, any>>
214+
| StoreConfig<any, any>
215+
| InjectionToken<StoreConfig<any, any>>,
202216
config: StoreConfig<any, any> | InjectionToken<StoreConfig<any, any>> = {}
203217
): ModuleWithProviders<StoreFeatureModule> {
204218
return {
@@ -207,13 +221,16 @@ export class StoreModule {
207221
{
208222
provide: _FEATURE_CONFIGS,
209223
multi: true,
210-
useValue: config,
224+
useValue: typeof featureNameOrSlice === 'string' ? config : {},
211225
},
212226
{
213227
provide: STORE_FEATURES,
214228
multi: true,
215229
useValue: {
216-
key: featureName,
230+
key:
231+
typeof featureNameOrSlice === 'string'
232+
? featureNameOrSlice
233+
: featureNameOrSlice.name,
217234
reducerFactory:
218235
!(config instanceof InjectionToken) && config.reducerFactory
219236
? config.reducerFactory
@@ -233,12 +250,21 @@ export class StoreModule {
233250
deps: [Injector, _FEATURE_CONFIGS, STORE_FEATURES],
234251
useFactory: _createFeatureStore,
235252
},
236-
{ provide: _FEATURE_REDUCERS, multi: true, useValue: reducers },
253+
{
254+
provide: _FEATURE_REDUCERS,
255+
multi: true,
256+
useValue:
257+
typeof featureNameOrSlice === 'string'
258+
? reducersOrConfig
259+
: featureNameOrSlice.reducer,
260+
},
237261
{
238262
provide: _FEATURE_REDUCERS_TOKEN,
239263
multi: true,
240264
useExisting:
241-
reducers instanceof InjectionToken ? reducers : _FEATURE_REDUCERS,
265+
reducersOrConfig instanceof InjectionToken
266+
? reducersOrConfig
267+
: _FEATURE_REDUCERS,
242268
},
243269
{
244270
provide: FEATURE_REDUCERS,

projects/example-app/src/app/auth/auth.module.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ export const COMPONENTS = [
2626
ReactiveFormsModule,
2727
MaterialModule,
2828
AuthRoutingModule,
29-
StoreModule.forFeature(fromAuth.authFeatureKey, fromAuth.reducers),
29+
StoreModule.forFeature({
30+
name: fromAuth.authFeatureKey,
31+
reducer: fromAuth.reducers,
32+
}),
3033
EffectsModule.forFeature([AuthEffects]),
3134
],
3235
declarations: COMPONENTS,

0 commit comments

Comments
 (0)