I have a fully populated object coming through from my server to my angular service. in postman I can see the entire object is there correctly.
even in the angular component that calls the service, when I JSON.stringify the object and print it to console it appears correctly. however, when I try to access that same object with angular in the view, I can only access the first level members of the object. when I try to access the existing nested object - I get: "TypeError: Cannot read properties of undefined". I thought maybe this had to do with the fact that those fields could be null, so I tried using ngIf, and conditional chaining - but then it just doesn't show those fields.
I will note, that the way I am trying to access this object is through children components. there is one "profile page" component that houses it's two children - view profile, and edit profile. and the object in question is passed down from the parent, and the issue is when I try to view it in the children.
the service http call:
GetCustomer(username: string) {
return this.http.get<Customer>(`${this.baseUrl}account/Customer/${username}`);
}
calling that in the "parent" profile component:
loadUserData() {
if(this.user){
if(!this.user.isAdmin){
this.accountService.GetCustomer(this.user.userName).subscribe(
c=>{this.customer = c}
)}
the customer interface(.ts) and it's nested address interface:
export interface Customer {
id: number;
firstName: string;
lastName: string;
userName: string;
email?: any;
avatar?: any;
creditInfo?: any;
address: Address;
orders: any[];
phoneNumber: number;
}
export interface Address{
id:number;
country:string;
city : string;
street:string;
houseNumber:number;
zip:string;
}
parent template:
<div *ngIf="EditMode">
<app-edit-profile [customer]="customer"
(customerChange)="UpdateCustomerData($event)"
(editMode)="toggleEditMode($event)"></app-edit-profile>
</div>
<div *ngIf="!EditMode">
<app-view-profile [customer]="customer" (editMode)="toggleEditMode($event)"></app-view-profile>
</div>
one of the children (they are both having the same issue):
export class ViewProfileComponent implements OnInit {
@Input() customer?:Customer;
@Output() editMode = new EventEmitter<boolean>();//this is to toggle between the children
constructor() { }
ngOnInit(): void {
}
toggleToEdit()
{
this.editMode.emit(true);
this.showjson();
}
showjson()
{
if(this.customer)
{
var jace = JSON.stringify(this.customer);
console.log(jace);
}
}
}
output of the json in console:
{"creditInfo":null,"adress":{"id":2,"country":"Peru","city":"Hong Kong","street":"Baker street","houseNumber":221,"zip":null},"orders":[],"phoneNumber":5000000,"id":6,"firstName":"John","lastName":"Smith","userName":"jan","email":"John@gmail.com","avatar":null}
in the child template, when I try to read first level values like customer.email it shows them just fine, but when I try to get the inner properties of address I get the above error.
<section class="vh-100" *ngIf="customer">
...
<p class="text-muted" >{{customer.firstName}}</p> // this works
<p class="text-muted">{{customer.address.country}}</p>//this causes the error
kaboom!:
core.mjs:6461 ERROR TypeError: Cannot read properties of undefined (reading 'country')
at ViewProfileComponent_section_0_Template (view-profile.component.html:48:45)
at executeTemplate (core.mjs:9593:1)
at refreshView (core.mjs:9459:1)
at refreshEmbeddedViews (core.mjs:10584:1)
at refreshView (core.mjs:9483:1)
at refreshComponent (core.mjs:10630:1)
at refreshChildComponents (core.mjs:9255:1)
at refreshView (core.mjs:9509:1)
at refreshEmbeddedViews (core.mjs:10584:1)
at refreshView (core.mjs:9483:1)
I tried to only include the relevant necessary things, hope I didn't miss anything important.
I have read a bunch of other posts I could find on the matter and none seemed to have the answer for me.
any help would be greatly appreciated. thanks!
Typo alert! the 'address'
field is declared in your interface, and what you're trying to read. But, 'adress'
field is the field present in your JSON (customer data).