Search code examples
angulartypescriptapiangular-httpclient

How to GET nested [object Object] data from http client in Angular app?


I have problem with write specific nested data in component. I loaded keys data (brands) from api but value nested data (models) not work and only write [object Object]. This data I GET from server to console:

IMAGE

and this show me at the monitor: IMAGE.

In the console I have this ERROR: ERROR TypeError: Cannot read property 'map' of undefined.

I expecting for example this:

AUDI - AUDI (brands)
A1 (models)
A2
A3
A4...

BMW
M1
M3
M5...

Do you know how resolve this? Thank you for your help.

My code:

app.component.ts

vehicleLists: VehicleLists[] = [];

  constructor(
    private vehicleService: VehicleService,
    private router: Router,
    private vehicleListAdapter: ListAdapter,
  ) {

  }

  ngOnInit(): void {
    this.getLists();
  }

  public getLists() {
    this.vehicleService.getVehicleLists().subscribe(({ brands, models }) => {
      console.log(brands);
      this.vehicleLists = brands;
      models.map(model =>
        this.vehicleLists.push(this.vehicleListAdapter.adapt(model)));
    });
  }

app.component.html

<div *ngFor="let item of vehicleLists">
  <p>{{item.id}} - {{item.name}}</p>
    <p>{{item.models}}</p>
</div>

lists.ts - model

export class VehicleLists {
  id: string;
  name: string;
  models: VehicleModel[];
}

export class VehicleModel {
  name: string;
  description: string;
}

vehicle-list.adapter.ts

export class ListAdapter implements Adapter<VehicleLists> {
  adapt(item: any): VehicleLists {
    const obj = new VehicleLists();
    obj.name = item.name;
    obj.id = item.id;
    obj.models = item.models;
    return obj;
  }
}

vehicle.service.ts

getVehicleLists() {
    return this.http.get<any>(environment.ApiUrl + `/api/url`);
  }

Solution

  • what you see is the normal behavior and totally expected. you can't use an object in html and expect it's content gets rendered. since item.models is an array and also it's not clear what is exactly the structure of a single model, however you have 2 options:

    1. use json pipe in your template:
    <div *ngFor="let item of vehicleLists">
      <p>{{item.id}} - {{item.name}}</p>
      <p>{{item.models | json}}</p>
    </div>
    
    1. use another ngFor on models and for each model specify the field you want to display:
    <div *ngFor="let item of vehicleLists">
      <p>{{item.id}} - {{item.name}}</p>
      <p *ngFor="let model of item.models>{{model.name}}</p>
    </div>