错误TypeError:无法读取未定义的属性X

时间:2018-08-02 14:48:12

标签: javascript json angular typescript mean-stack

我有以下接口可用作JSON文件的类型:

export interface IIndustrySectors {
  IndustrySector: string;
  isSelected: string;
  dataSubjectCategories:string[];
  dataTypeCategories:string[];
  SubIndustries:[{
    IndustrySector: string;
    isSelected: string;
    dataSubjectCategories:string[];
    dataTypeCategories:string[];
    SubIndustries:[{}]
  }]
}

,还有两项服务:

 
 
 // Read all the Data from the JSON file
 getMainIndustrySectors(): Observable<IIndustrySectors[]> {
    return this.http.get<IIndustrySectors[]>(this.industrySectorsURL).pipe(
      tap(((data) => console.log('All: ' + data) )),
      catchError(this.handleError)
    );
  }

//Get Specific object 
  getBySector(sector): Observable<IIndustrySectors|  undefined> {
    return this.getMainIndustrySectors().pipe(
      map((products: IIndustrySectors[]) => products.find(p => p.IndustrySector === sector)));

  }

这是JSON文件的一部分

 [
   {
      "IndustrySector":"Accommodation and Food Service Activities",
      "isSelected": "false",
      "dataSubjectCategories":["DS.Employees","DS.Collaborators"],
      "dataTypeCategories":"Personal Data",
      "SubIndustries": [
        {
          "IndustrySector":"Food and Beverage Service Activities",
          "isSelected": "false",
          "dataSubjectCategories":[],
          "dataTypeCategories":[],
          "SubIndustries":[]
        },
        {
          "IndustrySector":"Accommodation",
          "isSelected": "false",
          "dataSubjectCategories":["DS.Minor","DS.Parent","DS.Legal Person","DS.Natural Person","DS.Disable"],
          "dataTypeCategories":[],
          "SubIndustries":[]
        }
      ]
    }
  ]

问题是当我通过以下代码调用服务“ getBySector”时:

this.readjsonService.getBySector(sector).subscribe(response=>{

      if(response.dataSubjectCategories.length>0)
      {
        for(i=0; i<response.dataSubjectCategories.length;i++ ){
          this.DSofSectores.push(response.dataSubjectCategories[i])
        }
      }
      
      })
当我看到响应的类型时,它就是对象!

抛出错误:

  

TypeError:无法读取未定义“

的属性'dataSubjectCategories'

它会打印出值。

为什么?

基于该扇区的操作是,我“响应”与该扇区相关的其他数据,并填充一个绑定到下拉列表的字符串类型数组。它工作正常,但下图显示了选择子扇区后发生的情况:enter image description here

请帮助我,我是新手,对此我感到厌烦:(( 谢谢。

编辑: 当我说

 if (response == undefined) {
          throw new Error("sector not found");
        }
        else { .....

它通过条件,表示它不是未定义的,但是它说“无法读取未定义的”

3 个答案:

答案 0 :(得分:1)

filter方法找不到匹配项。因此,可观察的结果是产生undefined

getBySector(sector): Observable<IIndustrySectors|  undefined> {
     return this.getMainIndustrySectors().pipe(
        map((products: IIndustrySectors[]) => products.find(p => p.IndustrySector === sector)));
                                                     // ^^^ matches none
 }

答案 1 :(得分:1)

在您的getBySector服务中,您说:

products.find(p => p.IndustrySector === sector))

如果数组中没有对象与选择器匹配,则使用Array#find将返回undefined,在这种情况下,如果没有产品具有IndustrySector === sector。这就是为什么要求服务的返回类型为Observable<IIndustrySectors|undefined>的原因。

如果在编译时或在IDE中看到此错误,则是由于此返回类型引起的;它知道响应可以是undefined,因此,您必须考虑这种可能性。将使用方的代码更改为以下代码可以解决问题:

this.readjsonService.getBySector(sector).subscribe(response => {
  if (response !== undefined) {
    if(response.dataSubjectCategories.length > 0) {
      for(let i = 0; i < response.dataSubjectCategories.length; i++) {
        this.DSofSectores.push(response.dataSubjectCategories[i])
      }
    }
  }
})

但是请注意,这意味着,在运行时,如果传入的sector与任何产品都不匹配,则for循环不会执行

答案 2 :(得分:0)

  

TypeError:无法读取未定义“

的属性'dataSubjectCategories'

如上所述,建议您尝试访问未定义对象的dataSubjectCategories。因此,response不是对象。

使用response[0].dataSubjectCategories代替response.dataSubjectCategories

演示

var response = [
   {
      "IndustrySector":"Accommodation and Food Service Activities",
      "isSelected": "false",
      "dataSubjectCategories":["DS.Employees","DS.Collaborators"],
      "dataTypeCategories":"Personal Data",
      "SubIndustries": [
        {
          "IndustrySector":"Food and Beverage Service Activities",
          "isSelected": "false",
          "dataSubjectCategories":[],
          "dataTypeCategories":[],
          "SubIndustries":[]
        },
        {
          "IndustrySector":"Accommodation",
          "isSelected": "false",
          "dataSubjectCategories":["DS.Minor","DS.Parent","DS.Legal Person","DS.Natural Person","DS.Disable"],
          "dataTypeCategories":[],
          "SubIndustries":[]
        }
      ]
    }
  ];
  
 var DSofSectores = [];
if(response[0].dataSubjectCategories.length>0) {
  for(i=0; i<response[0].dataSubjectCategories.length;i++ ) {
    DSofSectores.push(response[0].dataSubjectCategories[i])
  }
}

console.log(DSofSectores);