Заполненный массив объектов возвращает 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 шт):
Проблема в асинхронном запросе 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)
})
Можно после получения данных проверить значение 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)
}
}
