I have an interface that looks like this:
export interface GeneralInfo{
Name: string;
Description: string;
}
Later in a component class, I have the following code
export class SignalsComponent implements OnInit {
objGeneral: GeneralInfo;
constructor(private _apiService: APIService)
openPopUp(){
this._apiService.getJsonData().subscribe(
(res => {
var tempJson = JSON.parse(res);
this.objGeneral = tempJson.General as GeneralInfo;
console.log("json --->", this.objGeneral.Description);
}),
(err => { })
);
}
}
When I look at the browser console all works and I see the data I expect to see. However, when I try to invoke the objGeneral.Description property in HTML, it fails. This is my HTML:
<div >
{{objGeneral.Description}}
</div>
What am I doing wrong?
Thank you
CodePudding user response:
1) Quick answer
Add a condition to your div :
<div *ngIf="objGeneral">
{{objGeneral.Description}}
</div>
Or use optional chaining if you still want to render an empty div :
<div >
{{objGeneral?.Description}}
</div>
Note that you can use optional chaining in condition :
<div *ngIf="objGeneral?.Description">
2) Complete answer
objGeneral
is still not defined when your DOM is rendering, it will be defined when the Observable completes. Means you are asking the DOM to render undefined data.
When I look at the browser console all works
Weird, because you should have this type of error in your console which prevents you to call the property of an undefined object :
ERROR TypeError: Cannot read properties of undefined (reading 'Description')
3) Ressources & useful links you might want to check for more information https://javascript.plainenglish.io/the-beauty-of-optional-chaining-in-typescript-32dd58ce1380
CodePudding user response:
The way you do it is incorrect - objGeneral exists only after async API call. Instead you should deliver this property via async pipe
export class SignalsComponent implements OnInit {
objGeneral$: BehavioutSubject<GeneralInfo> | null;
constructor(private _apiService: APIService)
openPopUp(){
this.objGeneral$ = this._apiService.getJsonData().pipe(
map(res => JSON.parse(res).General as GeneralInfo)
);
}
}
and use it as
<div *ngIf="objGeneral$ | async as objGeneral">
{{objGeneral.Description}}
</div>