Search code examples
angularngrxngrx-store

Data from @Input different in function than in template


I have a container that passes an Observable called positions$ to a component, which ultimately returns an array of objects. When I bind that array to the template, it displays the data as I would expect, but if I try to access that same data in one of my functions within that same component, it comes back with following:

enter image description here

That is logged to the console long after the expected data has displayed in the template, so I know I'm not clicking the button too quickly. Why aren't I getting the same data in both places? Here is my relevant code:

container typescript:

positions$: Observable<Position[]>;
...
this.positions$ = this.store.pipe(select(fromStore.getAllPositions));
this.store.pipe(select(fromStore.getPositionsLoaded)).subscribe(loaded => {
  if (!loaded) {
    this.store.dispatch(new fromStore.LoadPositions());
  }
});

container html:

<app-position-form
  [loading]="loading"
  [positions]="positions$"
  [positionsLoading]="positionsLoading$"
  (add)="addPosition($event)">
</app-position-form>

component typescript:

@Input() positions: Position[];
...
addPosition() {
    // Does NOT work as expected
    console.log('existing positions', this.positions);
}

component html:

<!-- Data displays correctly -->
<ul *ngIf="(positions | async)?.length">
  <li *ngFor="let position of (positions | async)">
    {{position.position}}
  </li>
</ul>

Solution

  • Your template that is working is using an async pipe to display the "postions", so "positions" appears to be an Observable.

    In the component that gets the @Input, you have the input typed as a Position[], but I'd bet that what you're actually getting at runtime is an Observable

    If so, the component will have to subscribe to the Observable to get the data.