Reputation: 2210
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
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
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
Reputation: 657496
Angular tries to bind before the data arrived.
<div>Id: {{contact?._id}} Name: {{contact?.name}}</div>
should work.
Upvotes: 1