访问对象数组时报Cannot read property of undefined错误如何解决
问题根源
你遇到的错误本质是两个问题叠加导致的:
- 数组未初始化:你只声明了
public arraydata3: BlockchainDB [];但没有给它赋初始空数组,它的初始值是undefined,调用push或者访问下标本身就会报错 - 异步请求时序错位:HTTP请求是异步执行的,你在构造函数中调用
createChainData触发两个请求后,立刻就尝试访问this.arraydata3[0].rxInfo,此时请求还没有返回结果,数组里还没有任何元素,哪怕你初始化了数组,arraydata3[0]也是undefined
至于你看到控制台打印arraydata3有2个元素,是Chrome控制台的特性:打印引用类型时会保存引用,你点开查看的时候请求已经返回、数组已经被填充了,并不是执行打印语句那一刻数组就有值,你可以换成console.log(JSON.stringify(this.arraydata3))验证,执行时数组是空的。
修复方案
第一步 初始化数组
把数组声明修改为:
public arraydata3: BlockchainDB [] = [];
第二步 调整异步逻辑
不要在构造函数里直接访问异步返回的结果,你可以用forkJoin合并两个请求,等所有请求都完成后再操作数据:
import { forkJoin } from 'rxjs'; import { tap } from 'rxjs/operators'; export class BlockchainService { // ...其他代码保持不变 constructor(private blockchainService: BlockchainDBService) { this.retrieveBlockchain(); // 等待所有请求完成后再访问数组 this.createChainData().subscribe(() => { console.log(this.arraydata3); console.log(this.arraydata3[0].rxInfo); }) } createChainData() { // 合并两个请求,统一等待返回 return forkJoin([ this.getBlockchain('1', 0), this.getBlockchain('2', 1) ]) } getBlockchain(id: string, seqnr: number) { return this.blockchainService.get(id).pipe( tap(data => { this.currentBlockchain = data; this.arraydata3.push(this.currentBlockchain); }) ) } }
如果不需要提前合并请求,也可以把访问数组的逻辑放到每个请求的subscribe回调里,或者在组件中用到数组的地方加可选链判断arraydata3?.[0]?.rxInfo,避免访问undefined的属性报错。
内容的提问来源于stack exchange,提问作者mysclz
相关产品推荐
相关产品推荐

