I'm having a service as follow:
public getDoseVignettes() : Observable<DoseVignetteApi> {
return this.apollo.watchQuery<Query>({
query: this.VIGNETTE
}).valueChanges
.pipe(
map(result => {
return result.data.doseVignettes;
}
));
}
which returns data as expected.
This service is called as follow:
doseVignetteApi! : DoseVignetteApi;
public ngOnInit(): void {
this.dataService.getDoseVignettes().subscribe(doseVignetteApi => {
// console.log("VIGNETTE : " JSON.stringify(doseVignetteApi)); [1]
this.doseVignetteApi = doseVignetteApi;
})
}
The console.log
[1] would display these data.
The front code is:
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px"
*ngFor="let vignette of this.doseVignetteApi!.vignettes!">
<mat-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>
The data will display on Chrome, but got the following issue with this code:
On Chrome debugger, got : Cannot read properties of undefined (reading 'vignettes')
As a consequence, the some others widgets aren't displayed (???)
Should I return an Observable from the service and use async
in *ngFor="let vignette of this.doseVignetteApi!.vignettes!"
or is there a way with using subscribe
as in the code above ?
EDIT: Solution 1
The recommendation of @MikeOne works: the exclamation mark in the HTML template should have been replaced by a question mark.
EDIT: Solution 2
Following the recommendation of @ZrelliMajdi, got it work as follow:
<ng-container
*ngIf="doseVignetteApi | async as dataServiceDetails">
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px"
*ngFor="let vignette of this.dataServiceDetails!.vignettes ">
<mat-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();
}
CodePudding user response:
You could subscribe on your observable on html template then consume its data:
<ng-container
*ngIf="dataService | async as dataServiceDetails">
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px"
*ngFor="let vignette of dataServiceDetails">
<mat-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>