0

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.

printscreen

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;
  }
5
  • 2
    Is getCars synchronous? Commented Feb 16, 2018 at 23:34
  • Is there some code missing here? I don't see a forEach. Commented Feb 16, 2018 at 23:34
  • instead of console.log(this.cars);, can you console.log(JSON.stringify(this.cars));. sometimes the browser takes time to log the value to the console, so it logs a value that is in the future. Commented Feb 16, 2018 at 23:34
  • this.cars.forEach(function(car) { console.log(car); }); should work if the cars array has elements console.log('number of cars: ' + this.cars.length); Commented Feb 16, 2018 at 23:45
  • getCars() looks very asynchronous due to the GET request and the following callback which fills the array. Commented Feb 17, 2018 at 0:30

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. The @djnose answer fixed the situation.
1

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

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.