Optimus Pette Optimus Pette - 1 year ago 87
AngularJS Question

Angular 2: In which lifecycle hook is input data available to the Component

I have a component which receives an array of

objects as

export class ImageGalleryComponent {
@Input() images: Image[];
selectedImage: Image;

I would like when the component loads the
value be set to the first object of the
array. I have tried to do this in the
lifecycle hook like this:

export class ImageGalleryComponent implements OnInit {
@Input() images: Image[];
selectedImage: Image;
ngOnInit() {
this.selectedImage = this.images[0];

this gives me an error
Cannot read property '0' of undefined
which means the
value isn't set on this stage. I have also tried the
hook but I'm stuck because i can't get information on how to observe changes of an array. How can I achieve the expected result?

The parent component looks like this:

selector: 'profile-detail',
templateUrl: '...',
styleUrls: [...],
directives: [ImageGalleryComponent]

export class ProfileDetailComponent implements OnInit {
profile: Profile;
errorMessage: string;
images: Image[];
constructor(private profileService: ProfileService, private routeParams: RouteParams){}

ngOnInit() {

getProfile() {
let profileId = this.routeParams.get('id');
profile => {
this.profile = profile;
this.images = profile.images;
for (var album of profile.albums) {
this.images = this.images.concat(album.images);
}, error => this.errorMessage = <any>error

The parent component's template has this

<image-gallery [images]="images"></image-gallery>

Answer Source

Input properties are populated before ngOnInit() is called. However, this assumes the parent property that feeds the input property is already populated when the child component is created.

In your scenario, this is not the case – the images data is being populated asynchronously from a service (hence an http request). Therefore, the input property will not be populated when ngOnInit() is called.

To solve your problem, when the data is returned from the server, assign a new array to the parent property. Implement ngOnChanges() in the child. ngOnChanges() will be called when Angular change detection propagates the new array value down to the child.