I have two features modules: Clients and Incomes
Both are lazy loaded and has own states.
Routes are something like this:
/clients - list of clients
/clients/1 - details of client
/incomes - list of incomes
/incomes/1 - details of income
But those features are not fully indepentent from each other.
On client's details page I want to show list of it's incomes. So ClientsModule has to import IncomesModule.
This works, but when I than go to /incomes I get Error: Store has already been added: incomes :/
How can I fix it? Or maybe it is a bug?
Should I split IncomesModule to two separate modules IncomesModule and IncomesStateModule?
If you add a state multiple times, you will get this error.
When it comes to domain entities and logic I find that I often want it to be global to the app.
Or be chunked in such a way that if you enter the settings route of the app, you load all of the settings states.
But for the majority it small to medium apps, keeping all your entities, states and api calls in one ng module called "domain" and loading that at startup works just fine, because then you can send actions between the states, such as update the client when the income changes.
Just split your domain module into multiple sections and have a barrel export which exports both the model, state, and actions for that part.
The biggest part of your app usually isn't the domain part, it's the views with all it's css and html.
So as long as you lazy load all your routes the load time should't be a problem.
Example
import { Client, ClientState, AddClientAction } from 'src/app/domain/client';`
client
index.ts
client.model.ts
client.state.ts
client.actions.ts
income
index.ts
income.model.ts
income.state.ts
income.actions.ts
Ok, that's good point and I'll move all domain related things to domain/config folder.
But what about using some components from IncomeModule like ex. <income-list>.
It's one of many components in IncomeModule that I need to use in ClientsModule.
Now ngxs is obstacle of such import.
In my opinion if You try to import the same slice of store You should skip it - not throw error and break app.
Eidt:
Maybe a param in NgxsModule's forRoot config? Like throwErrorOnDoubleStoreImport ?
The problem is that you call NgxsModule.forFeature(...) multiple times.
If you want to be able to import income components in another module, you should split the income module into the one that is lazy loaded, and a IncomeShared module that contains the reusable parts.
That way the route logic and ngxs stuff doesn't get imported two times.
I can understand that the error is frustrating, but ngxs is built around the same logic as angular services, if you would do the same thing with a service you would get two instances of the service which isn't what you want.
The only way getting around this is to only import the service once.
angular 6 has worked around this by the new providedIn: root, it might be that we can utilize that somehow to only create one instance of a state service, but I'm not sure how we could do that yet.
Thanks for help. I'll split IncomeModule into three:
IncomeCoreModule - with config and global store related things,
IncomeSharedModule - with shared components,
IncomeUiModule - with route related things,
Side note in master I removed this error since there are some use cases this could occur that are valid.
On my list is to write a store architecture documentation page too which would help with this.
Most helpful comment
Side note in master I removed this error since there are some use cases this could occur that are valid.
On my list is to write a store architecture documentation page too which would help with this.