Herman Fransen
Herman Fransen

Reputation: 2210

Angular2 Http Undefined error

I am trying to make a get request using the Http module in Angular2 (angular 2.0.0-beta.0 and typescript 1.7.5), but I have some kind of synchronise problem. I put everything in one .ts file to make it easier to communicate.

Everything compiles fine in typescript but Chrome shows the following error the in console :

EXCEPTION: TypeError: Cannot read property '_id' of undefined in [Id: {{contact._id}} Name: {{contact.name}} in Test@1:13]
ORIGINAL EXCEPTION: TypeError: Cannot read property '_id' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property '_id' of undefined
...
...
Object {_id: "5695e53d98ff94671ae22d55", name: "Piet Pannenkoek", email: "[email protected]", number: "435345"}

test1.ts:

import {bootstrap} from 'angular2/platform/browser';
import {Component} from 'angular2/core';
import {Http, Response, HTTP_PROVIDERS} from 'angular2/http';
import 'rxjs/Rx';

@Component({
    selector: 'my-app',
    template: `
        <div>Id: {{contact._id}} Name: {{contact.name}}</div>
    `,
    providers: [HTTP_PROVIDERS]
})

export class Test {

    public contact: Contact;

    constructor(private http: Http) {}

    ngAfterViewInit() {
        this.http.get('/api/contactlist/5695e53d98ff94671ae22d55')
            .map((res: Response) => res.json())
            .subscribe(res => {
                console.log(res);
                this.contact = res;
            });
    }
}

export class Contact {
    constructor (public _id: string, public name: string, public email: string, public number: string) {};
}

bootstrap(Test);

http://localhost:3000/api/contactlist/5695e53d98ff94671ae22d55

{"_id":"5695e53d98ff94671ae22d55","name":"Piet Pannenkoek","email":"[email protected]","number":"435345"}

Strange is that another (little different) version test2.ts doesn't give any errors:

import {bootstrap} from 'angular2/platform/browser';
import {Component} from 'angular2/core';
import {Http, Response, HTTP_PROVIDERS} from 'angular2/http';
import 'rxjs/Rx';

@Component({
    selector: 'my-app',
    template: '<div *ngFor="#contact of contacts">Id: {{contact._id}} Name: {{contact.name}}</div>',
    providers: [HTTP_PROVIDERS]
})

export class Test {

    public contacts: Contact[] = [];

    constructor(private http: Http) {}

    ngAfterViewInit() {
        this.http.get('/api/contactlist')
            .map((res: Response) => res.json())
            .subscribe(res => {
                console.log(res);
                this.contacts = res;
            });
    }
}

export class Contact {
    constructor (public _id: string, public name: string, public email: string, public number: string) {};
}

bootstrap(Test);

http://localhost:3000/api/contactlist

[{"_id":"5695e53d98ff94671ae22d55","name":"Piet Pannenkoek","email":"[email protected]","number":"435345"},{"_id":"56a63059b2cb5f4b10efaf9a","name":"Jan Janssen","email":"[email protected]","number":"642"},{"_id":"56a6307bb2cb5f4b10efaf9b","name":"Gerard de Boer","email":"[email protected]","number":"1234"},{"_id":"56abe853211b52a441f6c45f","name":"Bjorn Borg","email":"[email protected]","number":"123"},{"_id":"56abe8da211b52a441f6c460","name":"Hans Dobbelsteen","email":"[email protected]","number":"752"},{"_id":"56abe8fe211b52a441f6c461","name":"Marco van Basten","email":"[email protected]","number":"961"}]

Upvotes: 3

Views: 2057

Answers (3)

Pardeep Jain
Pardeep Jain

Reputation: 86750

you are trying to access contact object whihc is undefined/null till the template load i.e your object has not loaded properly at the time of template load. so to avoid this you have to use elvis operator like following

{{contact?._id}} and {{contact?.name}}

by using elvis operator angualr will not throw any error if your contact object has no value named name or id. whenever your binding load properly to contact Object angular will reflact changes to template.

try this one surely work for you.

<div>Id: {{contact?._id}} Name: {{contact?.name}}</div>

Upvotes: 2

dfsq
dfsq

Reputation: 193271

You are trying to use contact object before it's resolved. Either use elvis-operator {{ contact?._id }} or show block conditionally:

template: `
    <div *ngIf="contact">Id: {{contact._id}} Name: {{contact.name}}</div>
`,

Upvotes: 3

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657496

Angular tries to bind before the data arrived.

<div>Id: {{contact?._id}} Name: {{contact?.name}}</div>

should work.

Upvotes: 1

Related Questions