Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular ngrx-store: How to share store among modules (main module / feature module)

I have two angular modules: main and feature:

Main / root module:

@NgModule({
    imports: [
        StoreModule.forRoot({router: routerReducer}),
        EffectsModule.forRoot([...]),
        ...
    ],
    declarations: [],
    ...
})
export class AppModule {}

Feature module:

@NgModule({
    imports: [
        StoreModule.forFeature('feature', {someValue: someValueReducer}),
        EffectsModule.forFeature([...]),
        ...
    ],
    declarations: [],
    ...
})
export class FeatureModule {}

I need to access 'feature' slice of data in main module to conditionally display / activate application tab based on data stored in feature module.

(In other words I need a global / shared piece of state accessible by all modules main and any feature module.)

  1. Is it possible to do that?
  2. Is it considered as good practise?

Currently I can't do that since there is no feature state in main AppState:

export interface AppState {
    router: RouterReducerState<RouterStateUrl>;
}

And typescript indicates error this.store.select('feature') since there is no feature key of main store AppState.

Using selector: this.store.select(selectFeatureValue) I am getting runtime error:

export const selectFeatureModule = createFeatureSelector<FeatureState>('feature');
export const selectFeatureValue = createSelector(selectFeatureModule ,
(state: FeatureState) => state.someValue);

I am getting error in main AppComponent:

TypeError: Cannot read property 'someValue' of undefined

like image 396
Felix Avatar asked Oct 31 '17 06:10

Felix


People also ask

What is ngrx store in angular?

The Angular NgRx store is a client-side data management pattern that implements the Redux pattern, and which was invented by Facebook using RxJS observables. As a prerequisite, you need to be familiar with JavaScript and have Node.js and Angular CLI installed on your local development machine for this to work.

What is an example of ngrx?

For example, If your component needs new data from the API, the component dispatches an action, the reducers invoke the effects and services to the get the new data, reducer returns the new state with that data from API. NGRX is not for small Angular applications as there is so much boilerplate code.

How do I serve my application in angular 10?

You can serve your application using the following command: In this quick example, we learned how to use NgRX store in our Angular 10 example application; how we can dispatch actions; and seen how we can create reducers. I hope that you have found this article helpful, please leave any thoughts or questions in the comments!

Can I run ngrx on my local machine?

Here is the example project in the GitHub where you can clone and run it on your local machine. NGRX is a state management tool inspired by redux for the Angular Applications.


2 Answers

I think, this is a valid question at least partly. Imagine the following structure:

appState
├── coreState
│
├── lazyModuleSate1
│   ├── subStateA
│   └── subStateB
│
└── lazyModuleSate2
    ├── subStateA
    └── subStateB
  • coreState may hold common info about user, session...

  • Reducers of lazy modules may need to access such common state while processing actions.

    BUT

  • Reducer(s) of the core module see only coreState.

  • Reducers of lazy modules (defined with ActionReducerMap) see only their own subState. It is nice and clean for most of the cases, but sometimes, actions should be processed on condition of coreState. There would be no problem, coreState is always in the store.

  • Metareducers defined in the lazy modules see ONLY their own lazyModuleState. It is still useful, to handle interconnections between subStates, but they do not help with coreState - lazyModuleSate relations.

  • Only global metareducers defined at app level see the coreState. It is possible to handel actions here, although very ugly.

like image 53
bdi Avatar answered Oct 17 '22 09:10

bdi


My solution:

  • extracted extra feature module called core. I have refactored all shared global / state required by other modules into core.
  • added a dependency from all modules using shared state on core (no circullar dependency)
  • using selectors from core module there is no issue with typescript indicating there is no such key in store
like image 41
Felix Avatar answered Oct 17 '22 09:10

Felix