使用 Angular Observable:无法读取未定义的属性(读取 'foo')

Using Angular Observable : cannot read properties of undefined (reading 'foo')

我有如下服务:

  public getDoseVignettes() : Observable<DoseVignetteApi> {
    return this.apollo.watchQuery<Query>({
      query: this.VIGNETTE
    }).valueChanges
      .pipe(
        map(result => {
            return result.data.doseVignettes;
          }
        ));
  }

哪个 returns 数据符合预期。

此服务调用如下:


doseVignetteApi! : DoseVignetteApi;

public ngOnInit(): void {
     this.dataService.getDoseVignettes().subscribe(doseVignetteApi => {
        // console.log("VIGNETTE : " + JSON.stringify(doseVignetteApi)); [1]
        this.doseVignetteApi = doseVignetteApi;
      })
}

console.log [1] 会显示这些数据。

前面的代码是:

<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px" class="stats-cards"
     *ngFor="let vignette of this.doseVignetteApi!.vignettes!">
  <mat-card class="example-card" fxFlex="20">
    <mat-card-title>{{vignette!.aliasDose!}}</mat-card-title>
    <mat-card-content>
      <div *ngFor="let item of vignette!.items!">
        {{item.name}} : {{item!.total}}
      </div>
    </mat-card-content>
  </mat-card>
</div>

数据将显示在 Chrome,但此代码出现以下问题:

在 Chrome 调试器上,得到:Cannot read properties of undefined (reading 'vignettes') 因此,其他一些小部件未显示 (???)

我应该 return 服务中的 Observable 并在 *ngFor="let vignette of this.doseVignetteApi!.vignettes!" 中使用 async 还是有办法像上面的代码那样使用 subscribe

编辑:解决方案 1

@MikeOne 的推荐有效:HTML 模板中的感叹号应该换成问号。

编辑:解决方案 2

按照@ZrelliMajdi 的推荐,得到了如下效果:

<ng-container
  *ngIf="doseVignetteApi | async as dataServiceDetails">
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px" class="stats-cards"
     *ngFor="let vignette of this.dataServiceDetails!.vignettes ">
  <mat-card class="example-card" fxFlex="20">
    <mat-card-title>{{vignette!.aliasDose!}}</mat-card-title>
    <mat-card-content>
      <div *ngFor="let item of vignette!.items!">
        {{item.aliasVaccine}} : {{item!.totalByAlias}}
      </div>
    </mat-card-content>
  </mat-card>
</div>
</ng-container>
public ngOnInit(): void {
   this.doseVignetteApi = this.dataService.getDoseVignettes();
}

您可以在 html 模板上订阅您的 observable,然后使用它的数据:

<ng-container 
*ngIf="dataService | async as dataServiceDetails">
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px" class="stats-cards"
     *ngFor="let vignette of dataServiceDetails">
  <mat-card class="example-card" fxFlex="20">
    <mat-card-title>{{vignette!.aliasDose!}}</mat-card-title>
    <mat-card-content>
      <div *ngFor="let item of vignette!.items!">
        {{item.name}} : {{item!.total}}
      </div>
    </mat-card-content>
  </mat-card>
</div>
</ng-container>