@Input property is undefined in Angular 2's onInit

Angular

Angular Problem Overview


Trying to get the component's @Input value in constructor or ngOnInit. But it is coming as undefined all the time.

I updated the hero plunker with console.log to show the issue (beta angular). http://plnkr.co/edit/dseNM7OTFi1VNG2Z4Oj5?p=preview

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

What am I doing wrong here?

Angular Solutions


Solution 1 - Angular

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.

Solution 2 - Angular

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)
  }
}

Solution 3 - Angular

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.

Solution 4 - Angular

In the ngOninit method use,

ngOnInit() {
    if(this.hero) 
        console.log('hero', this.hero);
}

Solution 5 - Angular

@Barabas solution did not work in my case. I end up using this

export class HeroDetailComponent implements OnChanges {
    @Input() hero: any;

    ngOnChanges(changes: SimpleChanges){
        if(changes.hero && changes.hero.currentValue){
            let currentHero = changes.hero.currentValue;
            //use currentHero
        }
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioneesdilView Question on Stackoverflow
Solution 1 - AngularZyzleView Answer on Stackoverflow
Solution 2 - AngularTGHView Answer on Stackoverflow
Solution 3 - AngularBarabasView Answer on Stackoverflow
Solution 4 - AngularShubham ChandraView Answer on Stackoverflow
Solution 5 - AngularDaud OladipoView Answer on Stackoverflow