Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Response.json() bind to single object using interface - RxJs/Observable fails

This scenario works fine when the RESTful API returns a JSON array - but the web method I'm calling returns a single JSON object - and so the code has been converted to map a single object from <IRegistration[]> to <IRegistration> all the way up the stack.

This fails and the Chrome console returns an error showing the app could not find either of the mapped fields in the HTML

The HTML

{{myobject.productId}}
{{myobject.productName}}

The JSON

{
  "productId": 1,
  "productName": "My Field Value"
}

The Interface

export interface IRegistration {
    productId: number;
    productName: string;
}

The observable

getRegistration(): Observable<IRegistration> {
    return this._http.get(this._svcURL)
        .map((response: Response) => <IRegistration>response.json())
        .do(data => console.log('ALL: ' + JSON.stringify(data)))
        .catch(this.handleError);
}

The client component

myobject: IRegistration;

ngOnInit(): void {
    this._registrationService.getRegistration().subscribe(
        reg => this.myobject= reg,
        error => this.errorMessage = <any>error
    );
}

The error

 EXCEPTION: TypeError: Cannot read property 'productId' of undefined in [
{{myobject.productId}}
{{myobject.productName}}

 in SearchComponent@0:0]

The debugging I've done points to the response.json() in the observable failing to map correctly to the IRegistration - I can't seem to find the correct syntax?

like image 722
Alan Stephens Avatar asked Mar 29 '26 18:03

Alan Stephens


1 Answers

The code looks fine, I think the problem is that you don't initialize the myobject: IRegistration; before using it.

The doc for lifecycle hook ngOnInit() says:

Initialize the directive/component after Angular first displays the data-bound properties and sets the directive/component's input properties.

The data is displayed before the HTTP call returns any result so myobject is undefined when Angular is trying to render it.

You can use ? to ignore undefined properties such as {{ myobject?.productId }} or initialize the property first myobject: IRegistration = <IRegistration>{};.

like image 159
martin Avatar answered Apr 02 '26 03:04

martin