【问题标题】:ERROR TypeError: Cannot read property X of undefined错误类型错误:无法读取未定义的属性 X
【发布时间】:2018-08-02 14:48:11
【问题描述】:

我有以下接口用作 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”

不过,它会打印值。

为什么会这样?

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

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

编辑: 当我说

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

它通过了条件,意味着它不是未定义的,但它说“无法读取未定义”

【问题讨论】:

    标签: javascript json angular typescript mean-stack


    【解决方案1】:

    过滤方法找不到匹配项。所以 observable 产生了一个undefined

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

    【讨论】:

    • 我确信至少有一个可以找到。我怎样才能确保在代码中?
    • if (!response) { throw new Error("sector not found"); }
    • 是不是和说 if(response)..... 一样,它给出了这个错误:Expression has changed after it is checked。以前的值:'has-errors: false'。
    【解决方案2】:

    在您的getBySector 服务中,您说:

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

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

    如果您在编译时看到此错误,或者在您的 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 循环将不会执行 /strong>。

    【讨论】:

    • 我已经这样做了,现在给我“未定义”错误和“检查后表达式已更改。”
    • @user3075338 你应该console.log(response) 看看它是什么。
    • @cgTag 它是对象。它说 [object object]
    • 试试console.dir(response)
    • @user3075338 尝试使用 Chrome。它将在控制台中检查对象的内容。
    【解决方案3】:

    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);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 2021-11-22
      • 2018-07-12
      • 2021-12-16
      相关资源
      最近更新 更多