Rintales
Rintales

Reputation: 45

@Input() property in angular component returns empty array

I have calendar component with data property decorated as @Input():

import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-calendar',
  templateUrl: './calendar.component.html',
  styleUrls: ['./calendar.component.css']
})
export class CalendarComponent implements OnInit, OnChanges {
  @Input() data: CalendarDay[];

  constructor() {
    this.data = [];
  }

  ngOnInit() {
    this.initDays();
  }

  ngOnChanges(changes: SimpleChanges) {
    console.log(this.data);
    console.log(changes.data);
  }
}

I pass data in from another component like that:

<app-calendar [data]="this.calendarData"></app-calendar>

And passed data gets rendered by *ngFor in the calendar component (it renders perfectly and everything works just fine):

<div *ngFor="let item of data">{{item.date}}</div>

I want to parse this data first before rendering it into view and whenever i try to console.log data property within the calendar component i get strange array, its shows as empty, i can 'open' it from browser console:

Result of calling: console.log(changes.data.currentValue).

And when i try to log value like that:

console.log(this.data[0])

or

console.log(changes.data.currentValue[0])

i get undefined value.

Upvotes: 4

Views: 4226

Answers (1)

Shifenis
Shifenis

Reputation: 1125

Delete this.data = [] from constructor, avoid change anything when you use dependecy injecton.

And use set and get for each Input() that you want to use in your template, it's a best practice.

  private _data: CalendarDay[];

  @Input() set data(data: CalendarDay[]) {
    if(data) {
     this._data = data;
    }
  }

  get data(): CalendarDay[] {
    return this._data;
  }

And in your HTML you should pass it with:

<app-calendar [data]="calendarData"></app-calendar>

In calendar component you can use with

<div *ngFor="let item of data">{{item.date}}</div>

Upvotes: 6

Related Questions