Issue
I have this Angular code:
<mat-table [dataSource]="myData">
<ng-container matColumnDef="abc">
<mat-header-cell *matHeaderCellDef>Abc</mat-header-cell>
<mat-cell *matCellDef="let myData" [style.color]="getColor(myData.myVal)">{{ myData?.myVal }}</mat-cell>
</ng-container>
</mat-table>
.ts
@Input() myData: MyData[] = [];
standardColor:string = '';
warningColor:string = '';
constructor(
...
) {
this.getSettings();
}
getSettings(){
this.settings$ = this.settingsService.getSettings()
.pipe(shareReplay(),
catchError(error => {
this.onError();
return of({} as setting);
})
);
this.settings$.subscribe(result => {
this.standardColor = result.standardColor;
this.warningColor = result.warningColor;
});
}
getColor(myVal: number){
if(myVal > 0){
return this.standardColor;
} else {
return this.warningColor;
}
}
When getColor is executed in mat-cell, it is returning empty string.
Instead, it should return the value that comes from the observable (line this.standardColor = result.standardColor;
).
That is because the this.settings$ observable is asynchronous and is executing after the html template.
Understand this is usually solved by adding pipe async ( | asynch ) to the template.
But in this case it is a different observable (settings$), not the datasource in the template binding (myData).
Solution
Maybe you could convert getSettings() to an observable method and then wait for it to return the settings before showing your data:
myWarningColor: string = '';
myStandarColor: string = '';
settings$ = this.getSettings();
getSettings(): Observable<boolean> {
return this.settingsService.getSettings().pipe(
shareReplay(),
catchError((error) => {
return of({} as any);
}),
tap((result) => {
this.myWarningColor = result.warningColor;
this.myStandarColor = result.standardColor;
}),
switchMap(() => of(true))
);
}
Then in the template:
<div *ngIf="settings$ | async">
<div *ngFor="let item of myData">
<span [style.color]="this.getColor(item.myVal)">{{ item.myVal }}</span>
<span [style.color]="this.getColor(item.myVal)">COLOR</span>
</div>
</div>
Of course, that means that you must wait for the settings method to return before showing any data, but on the other hand, you would be displaying the wrong color coding if you don't have the settings.
Check this working example: https://stackblitz.com/edit/stackblitz-starters-7fn78y?file=src%2Fmain.ts
Answered By - Kari F.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.