Component-Store. Sharing Store with children components

2.6k Views Asked by At

Im trying to add this new library to a project, but Im having doubts regarding how to share the Page Component Store with its smart components children. I know that I could use Inputs and Outputs but I think that this approach were like tradicional ngrx used.

I think that I could use the component store with 'provide in root'. would this approach correct?

3

There are 3 best solutions below

0
Ben Rinehart On

There are a couple of ways to do it. You could create a facade service that references it in its providers array, but in my opinion this is not ideal as it kind of defeats the purpose of having a simple single file component-store to manage your component's state.

I found that I had to add the providedIn: 'root' setting to my decorator in order to share state between a parent and children components. I know that this is not ideal, but if you simply add it to each component's providers, I found out the hard way, that you will find you are accessing different instantiations of the component store and when you navigate to a new child component (even if the parent is in the view still), that the state will not be maintained because it will be a new state container. That's why I like using providedIn: 'root'.

0
PSZ On

I had the same issue today...

If you provide the WhateverStoreService in the root, the default behaviour is that one instance of the service is shared in the whole application. (It's some kind of global state again)

If you want a separate instance of a dependency to be shared across each instance of a component and its children, configure it on the component’s providers property.

@Component({
selector: 'parent-view',
templateUrl: './parent-view.component.html',
styleUrls: ['./parent-view.component.scss'],
providers: [WhateverStoreService]
})

Now you can inject the WhateverStoreService in the constructors of your parent and child components.

0
Maciej Wojcik On

It is all about the dependency providers and where you inject the instances.

  1. You may use the root - then you will end up with a single instance of your ComponentStore, available for the entire app. It is a good way for global data, like the number of items in the cart, for some e-commerce app. Then the code can look as follows:
    @Injectable({
      providedIn: 'root'
    })
    export class CartStore extends ComponentStore<CartState> {
    
  2. You may provide ComponentStore in the parent component, this will make it available for the child components of that parent. By that I mean all child and parent components will share the same instance of the ComponentStore. For that you can use the following code:
    @Component({
       selector: 'app-parent',
       providers: [ParentStore],
    })
    export class ParentComponent { ... }