Reputation: 12179
Why is this property undefined?
export class DataFormComponent implements OnInit {
distanceDropdownItems: any[];
constructor() { }
ngOnInit() {
this.distanceDropdownItems = DISTANCE_DROPDOWN_ITEMS;
console.log('FORMS dropdown items = ', this.distanceDropdownItems); < ---- defined ... [{},{},...]
}
}
Template:
<app-input-dropdown [dropdownItems]="distanceDropdownItems"></app-input-dropdown>
Child component:
@Component({
selector: 'app-input-dropdown',
templateUrl: './input-dropdown.component.html',
styleUrls: ['./input-dropdown.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class InputDropdownComponent implements OnInit {
@Input() dropdownItems: any[];
selectedItem: any;
constructor(private el: ElementRef) { }
ngOnInit() {
console.log(this.dropdownItems); <------- Undefined
this.selectedItem = this.dropdownItems[0];
const dropdownButton = this.el.nativeElement.querySelector('.dropdown-button');
dropdownButton.classList.remove('dropdown-button');
dropdownButton.classList.add('dropdown-input-button');
}
}
Upvotes: 0
Views: 1306
Reputation: 8468
You may have distanceDropdownItems undefined in parent. Check out the link below showing an example to share the data using Input decorator to child.
Share data from parent to child using Input decorator
If not, there could be another issue in the way the components are getting loaded in DOM, If child is placed in DOM before parent then ngOnInit()
call happens only for the first time at the time of Init. And that would cause your input to be undefined in child. So You may try to implement ngOnChanges()
in place of ngOnInit()
which will help in picking up the value chnage from parent if there is a delay in parent loading and passing data to child.
Use *ngIf
in your parent component to delay the initialization of the child component. You will bind the child component only if required object has a value.
Let me know if a code example would help and i can share here.
Upvotes: 0
Reputation: 2841
Since you are dealing with the child component and the @Input()
, i suggest you to do something like this :
@Component({
selector: 'app-input-dropdown',
templateUrl: './input-dropdown.component.html',
styleUrls: ['./input-dropdown.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class InputDropdownComponent implements OnInit , OnChanges{
@Input() dropdownItems: any[] = [];
selectedItem: any;
constructor(private el: ElementRef) { }
ngOnChanges(changes : SimpleChanges){
if(changes.dropdownItems.currentValue != undefined){
console.log(changes.dropdownItems.currentValue);
this.dropdownItems = changes.dropdownItems.currentValue ; // your dropdownItems will have data passed y component
console.log(this.dropdownItems); <------- won't be Undefined
this.selectedItem = this.dropdownItems[0];
const dropdownButton = this.el.nativeElement.querySelector('.dropdown-button');
dropdownButton.classList.remove('dropdown-button');
dropdownButton.classList.add('dropdown-input-button');
}
}
ngOnInit() {
}
}
Upvotes: 0
Reputation: 222542
You are using items
instead of distanceDropdownItems
as you showed in the parent component, try channging the variable name as follows,
<app-input-dropdown [dropdownItems]="distanceDropdownItems"></app-input-dropdown>
Also to avoid undefined or null errors, you could use *ngIf on the parent component to make sure dropdownItems dont throw any errors whenever you initialize the child component
<app-input-dropdown *ngIf="distanceDropdownItems" [dropdownItems]="this.distanceDropdownItems"></app-input-dropdown>
EDIT
now after the edit it looks like you are using wrong variable on the child component, change your variable as,
@Input() items: any[];
ngOnInit() {
console.log(this.items);
}
EDIT
With the latest edit, after you changed your input to dropdownItems
, the template on the parent component should be adjusted as,
<app-input-dropdown [dropdownItems]="items"></app-input-dropdown>
Upvotes: 2
Reputation: 547
It does not look like you have items
defined in your dropdown component. In your ngOnInit you should be logging dropdownItems
instead ro rename the name of input property to items
. Also in the parent HTML you should be defining the child component with [dropdownItems]=items
Upvotes: 0