Angular中*ngFor正常显示数据但控制台报undefined错误求助
解决Angular *ngFor中'Cannot read property 'participantIdentities' of undefined'错误
我来帮你梳理下问题的根源,这个错误主要是异步数据加载时机和模板变量引用错误两个原因导致的,咱们一步步解决:
1. 核心问题:异步数据未完成加载时模板已开始渲染
你的Matchinfo是通过matchService.GetMatch()这个HTTP请求异步获取的,当Angular渲染模板的时候,这个请求还没返回结果,所以arg.Matchinfo此时是undefined,尝试访问它的participantIdentities属性自然会报错。
解决方法:添加空值判断
可以通过两种方式避免这种情况:
- 方式一:用
*ngIf先判断arg.Matchinfo是否存在,再渲染内部内容 - 方式二:使用Angular的可选链操作符
?.,安全访问嵌套属性
修改后的HTML代码(方式一推荐):
<div class="match1" *ngFor="let arg of Matchlists.matches" style="margin-top: 40px;" > <!-- 先确认Matchinfo已加载完成,再渲染内部列表 --> <div *ngIf="arg.Matchinfo"> <div *ngFor="let part of arg.Matchinfo.participantIdentities"> <div *ngIf="part.player.accountId == accountid"> {{arg.Matchinfo.participants[part.participantId-1].spell1Id | summonerSpell }} {{arg.Matchinfo.participants[part.participantId-1].spell2Id | summonerSpell }} {{arg.Matchinfo.gameId }} {{arg.Matchinfo.participants[part.participantId-1].championId | championname }} </div> </div> </div> </div>
方式二(可选链写法):
<div class="match1" *ngFor="let arg of Matchlists.matches" style="margin-top: 40px;" > <div *ngFor="let part of arg.Matchinfo?.participantIdentities"> <div *ngIf="part?.player?.accountId == accountid"> {{arg.Matchinfo?.participants[part.participantId-1]?.spell1Id | summonerSpell }} {{arg.Matchinfo?.participants[part.participantId-1]?.spell2Id | summonerSpell }} {{arg.Matchinfo?.gameId }} {{arg.Matchinfo?.participants[part.participantId-1]?.championId | championname }} </div> </div> </div>
2. 次要问题:模板变量引用错误
你在HTML里写了{{Matchlist.Matchinfo.participants[...]}},但这里的Matchlist并不是当前循环的项,循环变量是arg,所以应该改成arg.Matchinfo.participants[...],否则Angular找不到对应的变量。
额外优化:管理订阅避免内存泄漏
你的组件里嵌套了多层HTTP订阅,建议统一管理这些订阅,避免组件销毁后订阅仍存在导致内存泄漏:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs'; // 其他导入保持不变 @Component({ selector: 'app-profil', templateUrl: './profil.component.html', styleUrls: ['./profil.component.css'] }) export class ProfilComponent implements OnInit, OnDestroy { // 新增订阅管理对象 private subscriptions = new Subscription(); // 其他属性保持不变 ngOnInit() { const baseSub = this.baseService.Getinfo("capman").subscribe((data: Account) => { console.log(data); this.account = data; this.accountid = data.accountId; const leagueSub = this.leagueService.Getleaugue(data.id).subscribe((leauguedata: League[]) => { this.leagues = leauguedata; this.leagues = this.leagues.filter(item => item.queueType !== "RANKED_TFT" && item.queueType !== "RANKED_FLEX_TT"); this.leagues = this.leagues.sort((b, a) => a.queueType.localeCompare(b.queueType)); }); this.subscriptions.add(leagueSub); const matchlistSub = this.matchlistService.Getmatchlist(this.accountid, 0, 5).subscribe((Matchlistdata: Matchlist) => { console.log(Matchlistdata); this.Matchlists = Matchlistdata; this.Matchlists.matches.forEach(va => { const matchSub = this.matchService.GetMatch(va.gameId).subscribe((Matchinfodata: Match) => { va.Matchinfo = Matchinfodata; console.log(this.accountid); }); this.subscriptions.add(matchSub); }); }); this.subscriptions.add(matchlistSub); }); this.subscriptions.add(baseSub); } // 组件销毁时取消所有订阅 ngOnDestroy() { this.subscriptions.unsubscribe(); } }
这样修改后,你的模板就能等异步数据加载完成后再渲染,同时修正了变量引用错误,控制台的undefined报错应该就会消失了。
内容的提问来源于stack exchange,提问作者Mehdi Kr
相关产品推荐
相关产品推荐

