Angular *用于显示数据但抛出';未定义';错误

Angular *用于显示数据但抛出';未定义';错误,angular,typescript,ngfor,Angular,Typescript,Ngfor,我有一个*ngFor指令,它按预期在浏览器中运行并显示数据。尽管我的chrome控制台显示“未定义”错误 http.service.ts: getExerciseProgress(exId: number): Observable<Exercise> { return this.http.get<Exercise>(this.baseURL + 'exercises/GetProgressionByExerciseId/' + exId) } 作为参数传递的

我有一个*ngFor指令,它按预期在浏览器中运行并显示数据。尽管我的chrome控制台显示“未定义”错误

http.service.ts:

getExerciseProgress(exId: number): Observable<Exercise> {
    return this.http.get<Exercise>(this.baseURL + 'exercises/GetProgressionByExerciseId/' + exId)
  }
作为参数传递的7用于测试目的,当我记录结果时,该对象似乎就是我要查找的对象。具有嵌套进度数组的练习对象

view-exercise.component.html:

<p *ngFor="let p of exercise.progress">{{ p.bpm }}</p>
提前感谢

您能试试这个吗:
{{p.bpm}


我的猜测是,即使您的数据不是init,angular也会首先尝试显示一些内容。

这是一个竞争条件:当模板第一次加载时,
此操作仍
未定义。然后,一旦可观测数据解析并分配了一个值,就会触发a,运行
*ngFor
,您就会看到这些值

有两种典型模式可以解决此问题:

使用(在您的情况下可能是最好的,因为您只有一个访问者):

在上面的示例中,我使用了一个
,因为它没有呈现到DOM中,但是您可以同样轻松地在真实元素上使用它,比如
。这通常用于
*ngIf=“exercise;else no data”
模式,其中
#no data
是另一个ng模板,在加载数据时替换div


仅供参考,因为Angular使用多边形填充,所以您可以安全地在您的打字脚本中使用。意思是,你可以写

this.baseURL + 'exercises/GetProgressionByExerciseId/' + exId
作为


有些人觉得这更容易阅读。

在服务调用完成并且您拥有可用数据之前,您的DOM似乎正在搜索练习中的进度对象

当API可用时,您应该对其进行循环,这意味着API调用已完成,并且您拥有以下数据:

<p *ngFor="let p of exercise?.progress">{{ p.bpm }}</p>
{{p.bpm}


或者使用
*ngIf
来实现它。

完成了任务,非常感谢。正如你所描述的,我去找猫王接线员。我也很感谢您的快速响应和额外的细节。@Gilmo很高兴我能提供帮助:)
<p *ngFor="let p of exercise?.progress">{{ p.bpm }}</p>
<ng-container *ngIf="exercise">
  <p *ngFor="let p of exercise.progress">{{ p.bpm }}</p>
<ng-container>
this.baseURL + 'exercises/GetProgressionByExerciseId/' + exId
`${this.baseURL}/exercises/GetProgressionByExerciseId/${exId}`
<p *ngFor="let p of exercise?.progress">{{ p.bpm }}</p>