@Input property is undefined in Angular 2's onInit

The reason you're getting undefined in ngOnInit is because at the point where the component is initialised you haven't actually passed in a Hero object

<my-hero-detail [hero]="selectedHero"></my-hero-detail>

At this point selectedHero has no value in your AppComponent and doesn't until the click event on the list calls the onSelect method

Edit: Sorry realised I didn't actually offer a fix. If you add an ngIf to my-hero-detail

<my-hero-detail *ngIf="selectedHero" [hero]="selectedHero"></my-hero-detail>

you should this will delay the initialisation of the my-hero-detail component and you should see the console output. This wont however output again when the selected hero changes.


This is because the heroes are loaded asynchronously, so when the view renders initially, the selected hero is undefined. But then after a selection is made, the hero is passed into the details view with a defined value.

You are basically just seeing the onInit call based on the original value (undefined).

If you want something similar to execute after each selection, you can modify it like this:

export class HeroDetailComponent implements AfterViewChecked {
  constructor(){
    console.log('hero', this.hero)
  }
  public hero: Hero;

  ngAfterViewChecked() {
    console.log('hero', this.hero)
  }
}

I encountered the same behavior when I've got undefined of Input property value in ngOnInit. The statement *ngIf="selectedHero" in html code was not satisfied me. Moreover, using AfterViewChecked from @THG's answer was not a good solution for me, because it calls periodically and also it causes the warning ExpressionChangedAfterItHasBeenCheckedError when I want to change some variable (I didn't want to use workaround setTimeout). This is my solution for kind of this issue:

export class MyComponent implements OnChanges {
    @Input() myVariable: any;

    ngOnChanges(changes: SimpleChanges) {
        if (changes['myVariable']) {
            let variableChange = changes['myVariable'];
            //do something with variableChange.currentValue
        }
    }
}

I hope it helps someone later.

Tags:

Angular