Platform: Allow for the dynamic insertion of StoreModule.forFeature store name, and initialState.

Created on 30 Jan 2018  路  5Comments  路  Source: ngrx/platform

In Angular, we have the ability to create a dynamic component. However, it would also be nice if we had the option to create a dynamic store. Right now, to the best of my knowledge, the best idea is to create a static facade/wrapper component, that feeds the store based on the dynamic child angular component event emitter(using @Output()).

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[x] Feature request
[ ] Documentation issue or request

What is the current behavior?

Currently a StoreModule.forFeature store is created on app initialization. Being that the store is created in the module, it respects AOT. Modifying the store from the component is not an option. Therefore, creating a dynamic store is not possible either.

Expected behavior:

Allow for the storeName for a module to be initialized from the component. Have StoreModule.forFeature be an observables, that expects a function to be run in the component with a specific name, and initial state. Reducer logic will remain in dynamic component.

For instance,
StoreModule.forLazyFeature('personFilter', reducer);

Inside the component, something along the lines of store.initiateLazyFeature('storeName', initialState);. This would allow for dynamic state, while still being immutable, increasing the productivity of every developer trying to create dynamic components, with the option of baking in reducer/action logic into component libraries.

Other information:

Thank you, and feel free to let me know what you think.

Most helpful comment

Does anyone have any examples as to how the ReducerManager is used? I'm trying to dynamically add/delete reducers, but I'm new to ngrx (used React/Redux before). I'm not entirely sure how the ReducerManager, ActionReducerMap, and InjectionTokens are all supposed to interplay. Any help on this would be very much appreciated!

All 5 comments

This actually exists as an underdocumented but stable API called the ReducerManager: https://github.com/ngrx/platform/blob/master/modules/store/src/reducer_manager.ts#L23

It will let you dynamically register reducers and features.

@MikeRyanDev just to confirm, is there the ability to initialize the storeName using ReducerManager?

Does anyone have any examples as to how the ReducerManager is used? I'm trying to dynamically add/delete reducers, but I'm new to ngrx (used React/Redux before). I'm not entirely sure how the ReducerManager, ActionReducerMap, and InjectionTokens are all supposed to interplay. Any help on this would be very much appreciated!

Here is how to use it:
this.reducerManager.addReducer("myFeatureName", myReducer);

This actually exists as an underdocumented but stable API called the ReducerManager: https://github.com/ngrx/platform/blob/master/modules/store/src/reducer_manager.ts#L23

It will let you dynamically register reducers and features.

How can we get the right Store object? I tried injecting StoreFeatures and finding it by the key.

  public constructor(
    @Inject(STORE_FEATURES) private storeFeatures: StoreFeature<any>[],
    private reducerManager: ReducerManager,
  ) {
  }

  public ngOnInit() {
    const feature =  this.storeFeatures.find(it => it.key == 'todo');
    this.reducerManager.addFeature(feature);
  }

  public ngOnDestroy(): void {
    const feature =  this.storeFeatures.find(it => it.key == 'todo');
    this.reducerManager.removeFeature(feature);
  }

This code fails inside ngOnInit because the ReducerManager expects the feature to have reducers property, but it's undefined actually.

Was this page helpful?
0 / 5 - 0 ratings