Search code examples
angularcomponentsngrx-store

Angular, send selector store data to child component


I would like to ask you about solution for send data from selector, store - ngrx, to child component.

It is only:

public testValue;

 this.store$.select(selectorDataTest).subscribe(
        data => {
          this.testValue = data;
        }
    );

and in template just:

<child-component [testValue] = "testValue"></child-component>

I think about async etc.


Solution

  • When you use select to get some data from the store it is returned as an Observable, (please use select inside a pipe) that's why you correctly subscribed to this.store$.pipe(select(selectorDataTest)).

    This approach is better if you remember to unsubscribe, I have two approaches for you:

    1.
    dataSubscription: Subscription;
    
    ngOnInit() {
      this.dataSubscription = this.store$.pipe(select(selectorDataTest))
        .subscribe(data => this.testValue = data);
    }
    
    ngOnDestroy() {
      this.dataSubscription.unsubscribe();
    }
    
    2.
    componentDestroyed$ = new Subject();
    
    ngOnInit() {
      this.dataSubscription = this.store$
        .pipe(
          takeUntil(this.componentDestroyed$),
          select(selectorDataTest)
        )
        .subscribe(data => this.testValue = data);
    }
    
    ngOnDestroy() {
      this.dataSubscription.next();
      this.dataSubscription.unsubscribe();
    }
    

    And inside your child-component you have

    @Input() testValue: any;
    

    So your approach

    <child-component [testValue] = "testValue"></child-component>
    

    is also correct.

    However, if you don't want to handle subscriptions, Angular provides you the async pipe.
    Which accepts an Observable and subscribe and unsubscribe for you. That way you can just keep the Observable select returns you, like this:

    dataTest$: Observable<any>;
    
    ngOnInit() {
      this.dataTest$ = this.store$.pipe(select(selectorDataTest));
    }
    

    and on your parent.component.html

    <child-component [testValue]="testData$ | async"></child-component>
    

    And, once again, inside your child-component you have

    @Input() testValue: any;