为什么出现TypeError:_this.data.forEach不是函数

时间:2019-09-19 11:49:51

标签: arrays angular typescript object foreach

我正在尝试从后端检索数据。这些是我代码的相关部分:

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不是函数。我该怎么解决

修改 Dto模型

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

3 个答案:

答案 0 :(得分:1)

您以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总是返回包含内容,可分页,totalPages等的对象,那么您当然可以为其创建可重用类型。

Rxjs是Angular用于处理异步编程(例如HTTP调用或组件事件)的库。 Rxjs在管道中将异步操作链接在一起(因此调用.pipe)。在该管道内部,rxjs期望一连串的运算符将对异步数据进行操作。 map运算符获取输入值并返回一个新值,以便您预订的值已从HTTP响应转换为HTTP响应的.content字段。

通过这种方式可以修复所有TypeScript编译器错误,并允许您以后链接其他调用,例如在API超时时重试,捕获错误或合并其他HTTP调用。

答案 1 :(得分:1)

您的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) });
        }
    }

答案 2 :(得分:0)

这是因为您试图遍历对象而不是数组 我认为您可以尝试以下方法:

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