I'm working on a nx monorepo with angular and ngrx. I've created a library with its own state management and I would like to reuse it in several modules of the same app.
Library structure
fooLib
- foo.reducer.ts
- foo.actions.ts
- foo.selectors.ts
- foo.service.ts // kind of facade
- foo.feature.key.ts
- index.ts
FooModule
@NgModule({
imports: [
CommonModule,
StoreModule.forFeature(FOO_FEATURE_KEY, fooReducer)
...
],
})
export class FooModule {}
FooState selectors
export const selectFooState = createFeatureSelector<State>( FOO_FEATURE_KEY );
export const someSelector = () =>
createSelector(selectFooState, (state) => state.someValue)
All good, I import FooModule into my main App and it works as intended: I can see FOO_FEATURE_KEY
registered in global store and I can dispatch/select through foo.service.ts
(acting like a facade, hiding all state complexity behind some methods).
Now, my main App is organized in modules (with their own state) and some of them require also FooModule. Moreover, each of those modules should have its own unique and independent FooState.
Problem: StoreModule.forFeature(FOO_FEATURE_KEY, fooReducer)
will use the same key regardless the module where it's declared.
As a first attempt I've tried to nest FooState inside each AppState. Example:
interface FirstAppState {
loading: boolean;
value: string;
foo: FooState;
}
Problem: selectors now fails since FOO_FEATURE_KEY
is no longer registered on Root.
How can I keep all my logic (state included) inside a library AND include it in multiple modules of the same App? I was trying to customize FOO_FEATURE_KEY
through injection/providers so that each module can use its own key/name but I can not access it in selectors since they're not part of Angular but just pure functions/const.
To make things more complex, I also need to sync each state with localStorage (I'm currently using localStorageSync
lib). Not the primary problem, but just to keep in mind...
Thanks!
EDIT: as suggested in comment description did not describe correctly my problem. To make it more clear: FooState handles and performs actions on a quite complex data structure. This structure is used by several modules of the same app: the exposed api is the exactly the same but runtime data are different. I could just copy/paste those lib files inside each module but I'll end up in a ton of identical files and would be a nightmare to maintain...