I've been struggling for 2 days to compose states of a featureA ("scenarios") module and a nested featureB ("intents") module.
Here is the desired structure of my state (structure 1):
{
authentication: { ... },
router: { ... },
scenarios: {
resources: { ids: { ... }, entities: { ... } },
intents: {
resources: { ids: { ... }, entities: { ... } }
}
}
}
I'd be happy also with (structure 2):
{
authentication: { ... },
router: { ... },
scenarios: { ids: { ... }, entities: { ... } },
intents: { ids: { ... }, entities: { ... } },
}
Although it doesn't reflect the structure of my modules.
The problem with structure 1 is that scenarios/reducers/index.ts
exposes a ActionReducerMap
, scenarios/modules/intents/reducers/index.ts
also exposes a ActionReducerMap
and I don't know how to compose them. Everything I tried doesn't even compile because of type conflicts.
The problem with structure 2 is that the intents
part of the state keeps being dropped out of the state because of the IntentsModule
not being loaded at first page load and other reducers of the app doing their job.
Here is the code:
/scenarios/scenarios.module.ts:
import { reducers, getInitialState } from './reducers';
@NgModule({
imports: [
...,
ScenariosRoutingModule,
StoreModule.forFeature('scenarios', reducers, { initialState: getInitialState }),
EffectsModule.forFeature([ScenariosEffects]),
],
})
export class ScenariosModule {}
/scenarios/reducers/index.ts:
import * as fromRoot from '../../../app.reducers';
import * as fromScenarios from './scenarios.reducers';
import * as fromIntents from '../modules/intents/reducers';
export interface ScenariosState {
resources: fromScenarios.State;
intents: fromIntents.IntentsState;
}
export interface State extends fromRoot.State {
scenarios: ScenariosState;
}
export const reducers: ActionReducerMap<ScenariosState> = {
resources: fromScenarios.reducer,
intents: fromIntents.reducers, <-- This is the part with types conflicts
};
/scenarios/modules/intents/intents.module:
import { reducers, getInitialState } from './reducers';
@NgModule({
imports: [
...,
IntentsRoutingModule,
StoreModule.forFeature('intents', reducers, { initialState: getInitialState }), <-- Also this part seems to add 'intents' as a top-level property of state
EffectsModule.forFeature([IntentsEffects]),
],
})
export class IntentsModule {}
/scenarios/modules/intents/reducers/index.ts:
import * as fromIntents from './intents.reducers';
export interface IntentsState {
resources: fromIntents.State;
}
export interface State {
intents: IntentsState;
}
export const reducers: ActionReducerMap<IntentsState> = {
resources: fromIntents.reducer,
};
export function getInitialState(): IntentsState {
return {
resources: fromIntents.initialState,
};
}