Home > Software design >  angular reading null value for existing nested object
angular reading null value for existing nested object

Time:07-08

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.

  • Related