0

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...

gorlock
  • 1
  • 1
  • I don't think that what you're doing should be a problem when used in different *apps*. Maybe your question is about using Foo module in different modules in a single *app*? – kvetis Nov 05 '21 at 10:59
  • Yes, sorry my mistake, I'll change the question. Basically I've 2 "sub-app" (like "user-space" and "admin-space") merged into a single app and accessed through routing. Actually your point gave me an alternative, I could split them into separated apps... Anyway I'd like to find a way to reuse that FooModule in different modules in the **same** app. Any idea? Thank you! – gorlock Nov 05 '21 at 12:18
  • Does this answer your question? [Independent instances of the same NgRx feature module](https://stackoverflow.com/questions/49537571/independent-instances-of-the-same-ngrx-feature-module) – kvetis Nov 05 '21 at 12:39

0 Answers0