Ced
Ced

Reputation: 17337

ngrx `forFeature` with multiple related entities

We are trying adopt a forFeature pattern for our app. However the multiple features are related.

We have an application where multiple entity relationships are shown simultaneously.

For example consider we have the following entities

Where as model

ìnterface Product {
  countryId: string;
  currencyId: string;
  supplierId: string;
}

interface Supplier {
  name: string;
  harbourId: string;
  countryId: string;
}

Then in the product-detail page we display the currency & country of a product and also the name and country of the supplier.

Consider we also have a supplier-details page where we display the above supplier infos as well as its last 10 products.

The way all this is currently handled is with a store structure as such:

 - entities
 ---- product
 ---- supplier
 ---- currency
 ---- country
 ---- harbour
 - ui
 ---- other stuff ui related

This is done with a single store at the root.

However the app folder structure is divided as such:

 - features
 --- product
 ------ product.actions / product.reducer / product.effects / product.selector
 --- supplier
 ------ supplier.actions / supplier.reducer / supplier.effects / supplier.selector
 --- store 
 ------ reducers ( here we are importing all reducers to combine those)
 ------ harbour.actions / harbour.reducer / harbour.effects / harbour.selector
 ------ country.actions / country.reducer / country.effects / country.selector
 ------ currency.actions / currency.reducer / currency.effects / currency.selector

As you can see the folder structure is a bit disorganized, as I'm not yet sure where to put harbour, country & currency as some of them are kind of general entities.

However I'm looking at the forFeature bit of ngrx and I'm wondering how all this would fit together if we happen to use that and if features even can be used together.

Upvotes: 4

Views: 2421

Answers (1)

chrispy
chrispy

Reputation: 3612

forFeature is meant to be used for reducers that need to be registered in a lazy manner a la forChild compared to forRoot.

I think a rule of thumb for this would be:

If the reducer is needed only for a particular lazy-loaded module, then it should be a forFeature for that module so it will only be registered once that module is loaded.

Once the reducer needs to be shared across modules (lazy loaded or not), then it needs to be at a higher level of abstraction in your app and should go to the forRoot version (globally accessible "at startup")

In summation:

  • Your entity structure seems fine to me.
  • I would put harbour/country/currency similar to how you did the others for file structure.
  • Only use the slice of state in forFeature if it's only needed for that feature module, and that module is lazy loaded.

Upvotes: 3

Related Questions