0

Can somebody explain me, why in the following example the @Input is null if I access it in ngOnInit of OtherComponent (the http call was successful)?

SomeComponent:

@Component({   
selector: 'some-component',   
template: `<other-component [data]="observable$ | async"></other-component>`,   
styles: [``] }) 
export class SomeComponent  {

    observable$: Observable<any>;

    ngOnInit(): void {
      observable$ = this.http.get(...); // service call via angular httpClient 
    }

OtherComponent:

@Component({   
selector: 'other-component',   
template: `<div>...</div>`,   
styles: [``] }) 

export class OtherComponent  {

    @Input()
    data: any;

    ngOnInit(): void {
     // if I access this.data here, it is null
    }

According to the angular documentation the async pipe subscribes to an observable and returns the latest value it has emitted. So I thought, the async pipe will pass down the result of the http call and not null.

If I use *ngIf, the result of the http call is passed down and not null.

<other-component *ngIf="observable$ | async as observable" [data]='observable'>

Stackblitz example:

https://stackblitz.com/edit/angular-xghrjg

mp5er
  • 155
  • 13

2 Answers2

1

Template:

<other-component [data]='observable$ | async'>

OtherComponent:

@Component({   
selector: 'other-component',   
template: `<div>...</div>`,   
styles: [``] }) 

export class OtherComponent  {

    @Input()
    data: any;

    ngOnInit(): void {}

    ngOnChanges(){
      console.log(this.data);
    }
Suresh Kumar Ariya
  • 9,516
  • 1
  • 18
  • 27
1

The issue is that at the time child component (in your case OtherComponent) was initialized the data was not there yet because data is loaded asynchronously.

Because of that Angular has OnChanges lifecycle hook which then gives you ability to manage data as it changes coming as Input().

Documentation -> https://angular.io/guide/lifecycle-hooks#onchanges

Updated Stackblitz -> https://stackblitz.com/edit/angular-nkgcj9?file=src%2Fapp%2Fdummy.component.ts

Important piece is

ngOnChanges(changes) {
  this.transformedData = changes.data.currentValue; 
}
Bruno
  • 316
  • 3
  • 6
  • I know that it work with ngOnChanges, but I don‘t want to take care about any changes. The initial value of the observable contains all the data I need. I just don‘t understand why the value is null in ngOnInit. I thought the async pipe „resolves“ the values of the observable before ngOnInit is called. – mp5er Feb 21 '19 at 21:59