Angular中find查找数据时如何判断属性不存在并跳过无效项
问题说明
Angular项目中实现showInforme方法加载Drupal关联的报告文件时,当条目缺失drupal_internal__target_id属性、或关联文件在included列表中匹配不到时,控制台抛出空指针错误:ERROR TypeError: Cannot read properties of null (reading 'meta'),需要实现异常条目自动跳过的逻辑。
原有问题代码:
showInforme(){ this.buscadorService.getInforme() .subscribe((data: InformesCounter) => { const { data: myData, included: myIncluded } = data; myData.forEach((item: any) => { const myFid = myIncluded.find((element: any) => element.attributes.drupal_internal__fid === item.relationships.informe.data.meta.drupal_internal__target_id) item.relationships.informe.data.meta.uri = myFid.attributes.uri; }); this.infoFile = myData.map((data: { relationships: any;}) => data.relationships); }) }
配套原有模板代码:
<button type="button" class="button"> <span *ngIf="infoFile"> <a href="http://localhost{{infoFile[i]?.informe?.data?.meta.uri.url}}" target="_blank" hreflang="es">Informe</a> </span> </button>
报错根因
代码中缺少多层空值校验:
- 遍历数据时直接深度读取对象属性,链路中任意节点(如
informe.data为null、meta不存在)都会触发空指针 Array.find查找关联文件可能返回undefined,直接读取其属性会触发报错- 模板层仅判断了
infoFile是否存在,没有校验内部嵌套的uri属性,异常数据会被渲染成无效链接
修复实现
1. 服务层数据预处理(核心逻辑)
在数据赋值给组件属性前,提前过滤无效条目,给所有属性访问加可选链防护,匹配不到关联资源时直接跳过:
showInforme(){ this.buscadorService.getInforme() .subscribe((data: InformesCounter) => { const { data: myData, included: myIncluded } = data; // 第一步:过滤掉结构缺失、没有目标id的无效条目 const validEntries = myData.filter((item: any) => { return Boolean(item?.relationships?.informe?.data?.meta?.drupal_internal__target_id); }); // 第二步:遍历有效条目,匹配关联文件,匹配不到直接跳过 validEntries.forEach((item: any) => { const targetFid = item.relationships.informe.data.meta.drupal_internal__target_id; const matchedFile = myIncluded.find( (file: any) => file?.attributes?.drupal_internal__fid === targetFid ); // 没找到对应文件、或文件uri不存在,跳过当前条目不赋值 if (!matchedFile?.attributes?.uri) return; item.relationships.informe.data.meta.uri = matchedFile.attributes.uri; }); // 第三步:最终只保留有有效uri的条目,供模板渲染 this.infoFile = validEntries .filter(item => item?.relationships?.informe?.data?.meta?.uri?.url) .map(item => item.relationships); }) }
2. 模板层兜底校验
模板中增加uri的存在判断,只有链接地址有效时才渲染a标签,同时用属性绑定写法替换字符串插值拼接href,避免变更检测阶段的取值异常:
<button type="button" class="button"> <span *ngIf="infoFile?.[i]?.informe?.data?.meta?.uri?.url"> <a [href]="'http://localhost' + infoFile[i].informe.data.meta.uri.url" target="_blank" hreflang="es" > Informe </a> </span> </button>
优化点说明
- 用可选链操作符
?.做全链路空值防护,从语法层面避免访问null/undefined属性的报错 - 多层过滤逻辑提前剔除异常数据,无效条目不会进入后续赋值、渲染流程
- 对
find查找结果做非空判断,匹配不到资源时直接终止当前循环,不执行后续赋值 - 模板层做最终兜底校验,彻底避免空链接渲染
内容的提问来源于stack exchange,提问作者HomerO
相关产品推荐
相关产品推荐

