Заполненный массив объектов возвращает lenght = 0

Я выполняю запросы к серверу и добавляю их в массив объектов в сервисе:

async auth(login: string, password: string) {
    let data = this.ApiService.autorization(login, password);
    data = (isNullOrUndefined(await data)) ? [] : await data;
    this.ApiService.cars = data['cars'];

    for (let i = 0; i < this.ApiService.cars.length; i++) {
        let car = this.ApiService.cars[i];
        this.http.get('http://get/example/').subscribe((data) => {
            this.ApiService.carsPosition.push(data[0]);
        });
    }
  console.log(this.ApiService.carsPosition)
  console.log('lenght: ' + this.ApiService.carsPosition.length)
}

введите сюда описание изображения

Данные получены, но их длина равна нолю. И я не могу их использовать. Что делать?

Попробывал сделать данным способом:

var observables = [];
for (let i = 0; i < this.ApiService.cars.length; i++) {
    observables.push(this.http.get('http://get/example/').pipe(map(data=>data[0])))
}
Observable.forkJoin(observables).subscribe(cars =>{
    this.ApiService.carsPosition = cars;
    console.log(this.ApiService.carsPosition)
    console.log('lenght: ' + this.ApiService.carsPosition.length)
})

Массив я получаю, но forkJoin не выполняется.введите сюда описание изображения


Ответы (2 шт):

Автор решения: Grundy

Проблема в асинхронном запросе this.http.get('http://get/example/').

Так как запрос асинхронный, обработчик subscribe выполняется после выхода из цикла, поэтому в момент вызова console.log, массив действительно пуст.

Подробнее про то, почему при раскрытии показываются верные значения ответе на вопрос Странное поведение Javascript при передаче объекта по ссылке

Для решения можно собрать все запросы в массив, и с помощью метода .forkJoin дождаться результата:

var observables = [];
for (let i = 0; i < this.ApiService.cars.length; i++) {
    observables.push(this.http.get('http://get/example/').pipe(map(data=>data[0])))
}
Observable.forkJoin(observables).subscribe(cars =>{
    this.ApiService.carsPosition = cars;
    console.log(this.ApiService.carsPosition)
    console.log('lenght: ' + this.ApiService.carsPosition.length)
})
→ Ссылка
Автор решения: OPTIMUS PRIME

Можно после получения данных проверить значение i

async auth(login: string, password: string) {
  let data = this.ApiService.autorization(login, password);
  data = (isNullOrUndefined(await data)) ? [] : await data;
  this.ApiService.cars = data['cars'];

  let stop = this.ApiService.cars.length;
  for (let i = 0; i < stop; i++) {
    let car = this.ApiService.cars[i];
    this.http.get('http://get/example/').subscribe((data) => {
      this.ApiService.carsPosition.push(data[0]);

      if (i === stop - 1) finish.call(this); // <-
    });
  }

  function finish() {
    console.log(this.ApiService.carsPosition)
    console.log('lenght: ' + this.ApiService.carsPosition.length)
  }
}
→ Ссылка