Reputation: 5495
I'm trying to iterate over an array, but Angular refuses to step in into it...
The array is being filled as follows. As you can see, I'm printing it into the console, and I can see that the array was initialized and filled.
export class CarDetailsComponent implements OnInit, AfterViewInit {
cars: Array<Car>;
constructor(private carService: CarService) {}
ngOnInit() {
this.cars = this.carService.getCars();
console.log(this.cars);
}
}
The array will be consumed into a ngAfterViewInit()
. For debug purposes, the first thing that I did was to check if the array is ok. And it is. But, the console.log inside the loop is never called. Why?
ngAfterViewInit() {
console.log(this.cars);
for (let i in this.cars) {
console.log(i);
}
}
I also tried to for..of
, this.cars.slice()
and everything seems to be ok...
EDIT (addressing some suggestions in comments)
I added both log suggestions and they show that the array is empty. I've attached a printscreen that shows that console.log(this.cars)
shows a valid array, but this.cars.length
and JSON.stringify(this.cars)
doesn't.
Since I'm noob, I don't know why this behavior occurs. Probably it related with what @Ayman and @Codeepic pointed out.
EDIT 2
Regarding @Minko question, I think that it is synchronous. It looks like:
getCars(): Array<Car> {
var cars: Car[] = [];
this.http.get('//localhost:8080/cars).subscribe(data => {
for (let entry of <Array<any>>data) {
cars.push(entry);
}
});
return cars;
}
Upvotes: 0
Views: 1539
Reputation: 945
your method
getCars(): Array<Car> {
var cars: Car[] = [];
this.http.get('//localhost:8080/cars).subscribe(data => {
for (let entry of <Array<any>>data) {
cars.push(entry);
}
});
return cars;
}
will very likely always return an empty array. That is because the http request will take a while to get the cars from the server. Also since you can call an asynchronous call in javascript it will not wait until it gets a result and return it.
To wait until your array is filled you can use Promises.
getCars(): Promise<Car[]> {
return new Promise (allLoadedFromServer => {
var cars: Car[] = [];
this.http.get('//localhost:8080/cars).subscribe(data => {
for (let entry of <Array<any>>data) {
cars.push(entry);
}
allLoadedFromServer(cars);
});
}
}
now you can access the data via:
ngAfterViewInit() {
this.getCars().then(data=>{
this.cars = data;
for (let i of this.cars) {
console.log(i);
}
);
}
that should give you the expected result. Hope it helps
Upvotes: 1
Reputation: 154
This happens because you are making an http call (your get) and before getting the answer you are trying to use the response object, put your logic inside the subscribe.
Upvotes: 1
Reputation: 4122
carService.getCars()
method is asynchronous.
ngAfterViewInit
runs after the template was rendered but before the carService.getCars()
returns any results. That's why you don't see the console.log in for loop.
Upvotes: 2