Почему я получаю TypeError: _this.data.forEach не является функцией - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь получить данные из бэкэнда.Вот соответствующие части моего кода:

Вызов API

getData(PrimaryId:number):Observable<DataDto[]>{
  return this.httpClient.get(`${this.prefix}/<xyz>/${PrimaryId}/xyz`) as Observable<DataDto[]>
}

Компонент TypeScript

onRetrieveClicked() {
  this.xyzService.getData(this.PrimaryId).subscribe(
    (xyz: DataDto[]) => {
      this.xyz = xyz
      console.log(this.xyz)
      console.log(this.xyz.forEach((data)=>data.name) 
  })
}

Первый вывод console.log

{content: Array(1), pageable: {…}, totalPages: 1, totalElements: 1, last: true, …}
       content: Array(1)
       0: {name: max, name: null, asset: null,  …}
       length: 1
       ..........

Но когда я пытаюсь напечатать только имя во второй консоли, он говорит, что forEach не является функцией.Как я могу решить эту проблему

edit Dto model

export interface DataDto {
name: string
asset: abcDto 
status: StatusDto 
tasks: efgDto[]
nextDate: string
}

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Кажется, что this.xyz не является массивом, но имеет свойство массива с именем content, вы должны изменить свой объект ответа, чтобы принять его.

Вы можете проверить, являются ли ваши объектымассивы с помощью следующего метода

Array.isArray(obj)

Обновите ваш код до этого.

this.xyzService.getData(this.PrimaryId).subscribe(
  (xyz: NewObject) => {
    this.xyz = xyz
    console.log(this.xyz)
    //If you have doubts of what is comming is nice to check if your property is an array
    if(Array.isArray(this.xhy.content) {
        console.log(this.xyz.content.forEach((data)=>data.name) });
    }
}

Создайте новый объект для поддержки вашего ответа

class NewObject {
    content: Array<DataDto>
    // other values here
}

Другой подходэто как @Robin говорит в комментарии

this.xyzService.getData(this.PrimaryId).subscribe((xyz: {content: DataDto[]}) => 
        {
        this.xyz = xyz
        console.log(this.xyz)
        //If you have doubts of what is comming is nice to check if your property is an array
        if(Array.isArray(this.xhy.content) {
            console.log(this.xyz.content.forEach((data)=>data.name) });
        }
    }
1 голос
/ 19 сентября 2019

Переменная xyz, которую вы вводите как DataDto[], массив, на самом деле является объектом.Это можно увидеть в вашем console.log, массив будет заключен в [], а не {}

is an object --> {
  content: Array(1), pageable: {…}, totalPages: 1, totalElements: 1, last: true, …}
       content: Array(1)
       0: {name: max, name: null, asset: null,  …}
       length: 1
 } 

Данные, которые вы ищете, скорее всего, являются объектом ответа content, поэтому добавьте импортдля import {map} from 'rxjs/operators'; и преобразуйте данные, полученные из ответа:

this.xyzService.getData(this.PrimaryId).pipe(
  map((xyzResponse: any) => xyzResponse.content)
).subscribe(
  (xyz: DataDto[]) => {
    this.xyz = xyz;
    console.log(this.xyz);
    let dataNames = xyz.map(data => data.name);
    console.log(dataNames);
}

Я набрал xyzResponse как any, но вы можете создать для него тип многоразового использования, если API всегда возвращаетobject with content, pageable, totalPages, ...

Rxjs - это библиотека, которую Angular использует для обработки асинхронного программирования, такого как вызовы HTTP или события компонента.Rxjs объединяет асинхронные манипуляции в канал (отсюда и вызов .pipe).Внутри этого канала rxjs ожидает цепочку операторов, которые будут выполнять операции с асинхронными данными, один за другим.Оператор map принимает входное значение и возвращает новое значение, так что значение, на которое вы подписаны, было преобразовано из ответа HTTP в поле .content ответа HTTP.

Исправление работы таким способомвсе ошибки компилятора TypeScript и позволяют вам связывать дополнительные вызовы позже, например, повторять попытки, если время ожидания API истекло, или перехватывать ошибки, или объединяться с другими вызовами HTTP.

0 голосов
/ 19 сентября 2019

Это потому, что вы пытаетесь перебрать объект вместо массива, я думаю, вы можете попробовать это:

console.log(this.xyz.content.forEach((data)=>data.name) })
...