Search code examples
angularngrxangular2-servicesangular-servicesngrx-component-store

Where to provide angular services for storing data


I want to use ngrx component-store/service with a subject in my application, however I am in a situation where I am not sure whats best. I hope you can guide me in the right direction. (The following example is a simplified version of my real scenario).

  • I have a MoviesComponent with a MoviesStore, containing all movies.
  • Route /movies-list directs to the MoviesListComponent. The MoviesListStore holds a string which is used for searching in the list
  • Route /movies-detail directs to MoviesDetailComponent and the MoviesDetailStore saves the expaned sections in the page.

enter image description here

This works pretty well.

BUT: When I navigate back and forth between /movies-list and /movies-detail I want that both, searchFor and expandedSections will preserve its values. With the current architecture the values are discarded since the MoviesListStore and MoviesDetailStore are destroyed as I navigate between them.

Approach #1

I could just move the MoviesListStore and MoviesDetailStore the the provider of MoviesComponent. enter image description here

  • every component still has its own dedicated store
  • might be confusing since the store is not provided on the component's level?!

Approach #2

I could get rid of the MoviesListStore and MoviesDetailStore and put the data in into the MoviesStore like this enter image description here

  • The MoviesStore now holds every data, no clear separation. The store might become super big.

Solution

  • I think the Approach #2 is the one you should go with. I agree that when you have a data related only to a specific module or a components subtree there is no need to put it in global store, because of two reasons:

    1. It will be available everywhere in your application (using selector)
    2. ngrx global store is never destroyed, because it is provided in root. So once you create an instance of it, or you register a feature slice it will always be there, along with the data (you can clear the data manually, but reducer, effects, actions etc. of your feature stays there).

    The Approach #2 is actually called component "branch" state:

    This is the one when you define component store in one node and that state would be used down in the component tree as well

    This quote comes from How to use NgRx ComponentStore? - Alex Okrushko | NG-DE 2022. Using this approach, you will have one instance of component store for a specific component subtree. During the navigation between movies-list and movies-detail components, the data will be preserved, but once the "highest" node is destroyed (in your example its movies.component) the component store will also be destroyed along with the stored data. When the instance of movies.component is created, an instance of a movies.store.ts will be created as well.
    I also recommend checking component-store vs global store comparison in official NGRX docs. You might find some answers there as well