Reputation: 250
I've created component which takes an @Input()
value but I always get undefind
.
Here's my code:
parent.html
<added-item
[minItemValueLength]="minItemValueLength"
[maxItemValueLength]="maxItemValueLength"
[listOfItems]="listOfItems"
></added-item>
children.ts
export class AddedItemComponent implements OnInit, OnChanges{
@Input() minItemValueLength: number;
@Input() maxItemValueLength: number;
@Input() listOfItems: string[];
ngOnInit() {
console.log(this.minItemValueLength) // return 3
console.log(this.listOfItems) // return undefined
}
}
parent.ts
export class LocationsTabComponent implements OnInit {
listOfItems: string[];
minItemValueLength = 3;
maxItemValueLength = 15;
public ngOnInit(): void {
this.locationService.getLocations().subscribe((locations) => {
this.getLocationsList();
console.log(this.listOfItems) // return Array(6)
});
}
private getLocationsList() {
this.listOfItems = this.locations.map((location: Location) => location.name);
console.log(this.listOfItems) // return Array(6)
}
}
If I use ngOnChanges()
in children than it at first output me:
data undefined
and then:
data Array(6)
How can I get this value in onInit
?
Would be really grateful for any help!
Upvotes: 0
Views: 930
Reputation: 4302
Since your subscribing to the locations, you can use async to wait until the response is fully resolved or otherwise you have to implement OnChanges
interface.
public async ngOnInit(): void {
await this.locationService.getLocations().toPromise().then((locations) => {
this.getLocationsList();
console.log(this.listOfItems) // return Array(6)
});
}
private getLocationsList() {
this.listOfItems = this.locations.map((location: Location) => location.name);
console.log(this.listOfItems) // return Array(6)
}
Upvotes: 1
Reputation: 12196
The value isn't always undefined
only on the time the component is created, and this is because you passed as such.
Process:
ngOnInit
is starting.ngOnInit
has Observable\Promise\Async method, which means we're not waiting for the response, thus the value is still undefined.ngOnInit
. value still undefined.Observable\Promise\Async
method is now finally finished and custom callback you created now assigned the value, and the value is passed to the child component.
So of course child ngOnInit
will not accept it because the component was already created.There are couple of solutions:
*ngIf="listOfItems"
on added-item
.async ngOnInit
, change: .subscribe
to .toPromise
e.g: await this.locationService.getLocations().toPromise...
, now parent ngOnInit
will wait for response.Upvotes: 1
Reputation: 8623
This is because you assign
listOfItems = ...
in an async callback method.
If you want to detect the changes, you should implement onChanges interface and implement the corresponding hook method.
export class AddedItemComponent implements OnInit, OnChanges{
@Input() minItemValueLength: number;
@Input() maxItemValueLength: number;
@Input() listOfItems: string[];
ngOnInit() {
console.log(this.minItemValueLength) // return 3
console.log(this.listOfItems) // return undefined
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.listOfItems) {
console.log(this.listOfItems)
}
}
}
Upvotes: 2