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":"[email protected]","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 *ngIf="customer">
...
<p >{{customer.firstName}}</p> // this works
<p >{{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!
CodePudding user response:
Typo alert !
'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)
Cheers
CodePudding user response:
You receive data with property adress while your interface is address, I think you need to communicate with the backend to fix the typo of property.