[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
Lets assume that we have two modules:
@NgModule({
imports: [
StoreModule.forFeature('entities', reducer, { initialState }),
]
})
export class EntitiesModule {}
and
@NgModule({
imports: [
StoreModule.forFeature('entities', reducer, { initialState }),
]
})
export class UsersModule {}
As you can see, both modules are trying to use the same entities sub-state.
Expected app state is for example:
{
entities: {
users: {
1: {
name: 'user1'
comments: [1]
}
},
comments: {
1: { text: 'comment1' }
},
articles: { ... }
assignments: { ... }
}
}
I'm wondering if is it even possible in NGRX to have two modules which both work on the same feature. For example, EntitiesModule is responsible for fetching a data from API and UsersModule is responsible just for a user related data.
Problem is, that when I try to import both modules in AppModule, then reducer from the second module will override the reducer from first module.
I even try to update modules like this:
@NgModule({
imports: [
StoreModule.forFeature('entities', ENTITIES_REDUCERS, { initialState }),
],
providers: [
{ provide: ENTITIES_REDUCERS, multi: true, useValue: reducer}
]
})
export class EntitiesModule {}
and
@NgModule({
imports: [
StoreModule.forFeature('entities', ENTITIES_REDUCERS, { initialState }),
],
providers: [
{ provide: ENTITIES_REDUCERS, multi: true, useValue: reducer}
]
})
export class UsersModule {}
Now, both reducers works, however, state looks like this:
{
entities: {
0: { // initial state from EntitiesModule
users: {
1: {
name: 'user1'
comments: [1]
}
},
comments: {
1: { text: 'comment1' }
},
articles: { ... }
assignments: { ... }
},
1: { // initial state from UsersModule
users: {}
}
}
To summarise our issue:
We need to have multiple modules, which can operate on the same feature.
This is exactly the feature I was trying to implement today and I have not been successful. My use case is that I have 'site' and 'admin' lazy loaded modules and both of them have other lazy loaded sub modules underneath e.g. 'siteSubFeature1' and 'siteSubFeature2', 'adminSubFeature1' and 'adminSubFeature2'. Is this even possible? It would be good to have app State to reflect this hierarchy. For now I resorted to flat hierarchy instead.....
Feature states as implemented are meant to handle top level states. Adding merging of subtrees would add more complexity to the API and make it more difficult to reason where your feature state should be placed in the state object. Each feature state should have a distinct name.
The APIs already exist for you to do this using a service to store your composed reducer and a feature reducer token that uses the service to combine your reducers together when the feature is loaded.
Thanks for your answer.
@nihique Have you found a solution?
@brandonroberts Could you please provide an example of how to implement what @nihique mentioned?
Thanks!
@levgaas there is the root state and then there are immediate children (feature states). The hierarchy does not extend to a third level -- this is what is meant by "For now I resorted to flat hierarchy instead.....".
@brandonroberts, I appreciate your response to this question, but as I see you work on the NgRx documentation, I would like to suggest that the docs be clarified to avoid this confusion. (This issue was originally tagged as a "Documentation issue or request")
In particular, in the documentation section titled Feature Module State Composition it says
Store uses fractal state management, which provides state composition through feature modules, loaded eagerly or lazily
It is unclear what is meant by the term "_fractal state management_," but the only interpretation that I would infer from that statement implies that states are composed of feature modules which can each be composed of recursively nested sub-features.

Perhaps this section could be amended to clarify what is meant by "_fractal state management_" and be clear that "_feature states as implemented are meant to handle top level states._"
Feature states as implemented are meant to handle top level states. Adding merging of subtrees would add more complexity to the API and make it more difficult to reason where your feature state should be placed in the state object. Each feature state should have a distinct name.
The APIs already exist for you to do this using a service to store your composed reducer and a feature reducer token that uses the service to combine your reducers together when the feature is loaded.
@brandonroberts
Hi, can you maybe give an example or point me in the right direction how to do this?
I'm also looking at implementing this. We have an admin module that is lazy loaded, and that module is responsible for Create/Update/Delete of entities in the application. The entities live in an eagerly loaded slice because they are used frequently in the application.
So eagerly we have a reducer that reads from our backend, but lazily we want admin functionality.
If this isn't possible, I guess what's left is to reuse the entity from the app in the admin section and duplicate all data?
Why this is closed without any comment or summary? :thinking:
Most helpful comment
@brandonroberts, I appreciate your response to this question, but as I see you work on the NgRx documentation, I would like to suggest that the docs be clarified to avoid this confusion. (This issue was originally tagged as a "Documentation issue or request")
In particular, in the documentation section titled Feature Module State Composition it says
It is unclear what is meant by the term "_fractal state management_," but the only interpretation that I would infer from that statement implies that states are composed of feature modules which can each be composed of recursively nested sub-features.
Perhaps this section could be amended to clarify what is meant by "_fractal state management_" and be clear that "_feature states as implemented are meant to handle top level states._"