Почему я не могу перебирать элементы этого объекта? - PullRequest
1 голос
/ 09 мая 2020

Я новичок в TypeScript и JavaScript, и у меня проблема. У меня есть функция, которую я скопировал из другого приложения, но я немного изменил ее:

myServer.prototype.filterList = function(_data, filterModel) {
  const resultOfFilter = [];
  function filterData(filtModel) {
    let httpParams = new HttpParams();
    for (const f in filtModel) {
      // some code
    }
    const httpOptions = {
      params: httpParams,
    };
    return that.httpClient.get(`${baseUrl}${tableName}`, httpOptions);
  }

  filterData(filterModel).subscribe((filteredData: any[] ) => {
    filteredData.forEach((item) => {
      resultOfFilter.push(item);
    });
  });

  return resultOfFilter;
};

Эта функция возвращает такой массив: enter image description here

Я передаю этот массив другой функции, где хочу перебрать его элементы. Пробовал следующие подходы:

а)

resultOfFilter.forEach(i => {
    console.log('I:', i);
  });

б)

for (let i; i <= resultOfFilter.length; i++){console.log('I:', resultOfFilter[i]);}

c)

Object.keys(resultOfFilter).forEach(i => {
    console.log('I:', i);
  });

Но все эти функции у меня не сработало. И я не могу понять почему. Я могу отобразить весь массив, но по какой-то причине не могу получить его элементы. Посоветуйте, пожалуйста, как получить каждый элемент этого массива. PS: Когда я использую typeof resultOfFilter, я получаю object.

Ответы [ 2 ]

2 голосов
/ 09 мая 2020

у вас асинхронная проблема. вы возвращаете resultOfFilter, но ваш запрос на получение за это время обрабатывается. вам нужно дождаться завершения вашего запроса, после чего вернуть resultOfFilter

myServer.prototype.filterList = async function(_data, filterModel) {
  const resultOfFilter = [];
  function filterData(filtModel) {
    let httpParams = new HttpParams();
    for (const f in filtModel) {
      // some code
    }
    const httpOptions = {
      params: httpParams,
    };
    return that.httpClient.get(`${baseUrl}${tableName}`, httpOptions);
  }

  const filteredData = await filterData(filterModel).toPromise();

  filteredData.forEach((item) => {
      resultOfFilter.push(item);
  });


  return resultOfFilter;
};

Пример использования

import { Component, OnInit } from '@angular/core';
import { myServer } from 'path-to-service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  constructor(private myServer: myServer) { }

  ngOnInit() {
     this.getResultOfFilter();
  }

  async getResultOfFilter() {
   let result = await this.myServer.filterList(data, filterModel);
   console.log(result, 'getResultOfFilter');
  }
}

или

import { map } from 'rxjs/operators';

myServer.prototype.filterList = function(_data, filterModel) {
  const resultOfFilter = [];
  function filterData(filtModel) {
    let httpParams = new HttpParams();
    for (const f in filtModel) {
      // some code
    }
    const httpOptions = {
      params: httpParams,
    };
    return that.httpClient.get(`${baseUrl}${tableName}`, httpOptions);
  }

  return filterData(filterModel).pipe(
    // map operator should be imported from `rxjs/operators`
    map(filteredData => {
      filteredData.forEach((item) => {
        resultOfFilter.push(item);
      });

      return resultOfFilter;
    })
  );


};

Пример использования

import { Component, OnInit } from '@angular/core';
import { myServer } from 'path-to-service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  constructor(private myServer: myServer) { }

  ngOnInit() {
     this.getResultOfFilter();
  }

  getResultOfFilter() {
    this.myServer.filterList(data, filterModel).subscribe(result => {
      console.log(result, 'getResultOfFilter');
    });
  }

}
0 голосов
/ 09 мая 2020

используйте async и await

myServer.prototype.filterList = async function(_data, filterModel) {

  const filterData = async function (filtModel) {
    let httpParams = new HttpParams();
    for (const f in filtModel) {
      // some code
    }
    const httpOptions = {
      params: httpParams,
    };
    return that.httpClient.get(`${baseUrl}${tableName}`, httpOptions);
  }

  await (await filterData(filterModel)).pipe(map((filteredData: any[] ) => {
    const resultOfFilter = [];
    filteredData.forEach((item) => {
      resultOfFilter.push(item);
    });
    return resultOfFilter;
  }));

};

httpClient.get - это асинхронная операция, для получения данных требуется некоторое время. Отметьте все асинхронные функции с помощью async и используйте await при вызове асинхронных функций для возврата обещаний.

Надеюсь, это поможет!

Обновление: эта функция возвращает наблюдаемый объект, на который можно подписаться, чтобы получить значение.

Другой вариант - заменить await (await filterData(filterModel)).pipe(map(...)) на await (await filterData(filterModel)).toPromise().then(...), чтобы вместо этого вернуть Promise.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...