0
votes

I'm new in angular v4 and I have problems with parse nested object from de rest api,Its a very simple case I'll let the code speak for me, its a really basic code but I dont find the error.

The error

ERROR TypeError: Cannot read property 'email' of undefined at Object.eval [as updateRenderer] (CarDetailComponent.html:7) at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:12679) at checkAndUpdateView (core.es5.js:12058) at callViewAction (core.es5.js:12367) at execComponentViewsAction (core.es5.js:12313) at checkAndUpdateView (core.es5.js:12059) at callViewAction (core.es5.js:12367) at execComponentViewsAction (core.es5.js:12313) at checkAndUpdateView (core.es5.js:12059) at callWithDebugContext (core.es5.js:13041)

Classes

import { JsonObject, JsonProperty } from "json2typescript";

@JsonObject
export class User {
  @JsonProperty("id", Number)
  public id: number = undefined;
  @JsonProperty("email", String)
  public email: string = undefined;
  constructor(
  ) { }
}

@JsonObject
export class Car {
  @JsonProperty("id", Number)
  public id: number = undefined;
  @JsonProperty("brand", String)
  public brand: string = undefined;
  @JsonProperty("createdby", User)
  public createdBy: User = undefined

  constructor(
  ) { }
}

(Service: car.service.ts)

import { Injectable } from '@angular/core';
import { Car } from "app/car/car";
import { Observable } from "rxjs";
import 'rxjs/Rx';
import { Http } from "@angular/http";

@Injectable()
export class CarService {
  private baseHost: string = "url/to/api";

  constructor(private _http: Http) { }
  get(id: number) {
    return this._http.get(this.baseHost + id + '/show.json')
      .map(data => data.json()).toPromise();
  }
}

(Component: car-detail.component.ts)

import { Component, OnInit } from '@angular/core';
import { CarService } from "app/car/car.service";
import { Car, User } from "app/car/car";


import { JsonConvert } from "json2typescript"

@Component({
  selector: 'app-car-detail',
  templateUrl: './car-detail.component.html',
  styleUrls: ['./car-detail.component.css'] 
})
export class CarDetailComponent implements OnInit {
  public car:Car = new Car();
  public createdBy:User = new User();
  constructor(private _carService: CarService) { }

  getCar(){
    return this._carService
               .get(1) 
               .then(
                  data =>
                   {this.car = JsonConvert.deserializeString(JSON.stringify(data), Car);
                    this.createdBy = JsonConvert.deserializeString(JSON.stringify(data.createdby), User); 
                    console.log(data,JSON.stringify(data))
                  });
  }

  ngOnInit() {
    this.getCar();
  }

}

(car-detail.html)

<p>
  car-detail works!
</p>
<p>
  {{car.brand}} print: FORD 
</p>
<p>
  {{car.createdBy.email}} print: [email protected] //It's ok but this line is the problem  
</p>
<p>
  {{createdBy.email}} print: [email protected]
</p>
1

1 Answers

1
votes

The component creates a new Car and assigns it to its car field. The createdBy field of this car object is set to undefined. And the template tries to display the property email of the car's createdBy, which is undefined. Hence the error.

Use

{{car.createdBy?.email}}

or

<p *ngIf="car.createdBy">
  {{ car.createdBy.email }}
</p>

to avoid the error.