Reputation: 1694
I am trying to learn angular 2 and I cannot get the most simple http get to work.
I get the runtime error
Cannot read property 'id' of undefined
But at the same time the value of 'id' is being shown on the page which confuses me a lot. How can it be undefined and still be shown.
I get this json returned from the WebApi
{
"category":["some string"],
"icon_url":"some string",
"id":"some string",
"url":"some string",
"value":"some string"
}
I have created an interface
export interface IProduct {
category: string;
icon_url: string;
id: string;
url: string;
value: string;
}
In my service I have this method that call the webApi and returns the json
getproducts(context: ContentAndStructureContext): Observable<IProduct[]> {
return this.http.get(routes.url(context), { cache: true })
.map((res: Response) => <IProduct[]>res.json())
.do(data => console.log(data));
}
That works fine and the data object is being logged to the console. So far so good
in my component I have call the getProducts method
export class HomeComponent implements OnInit {
isProductLoading: boolean;
iproducts: IProduct[];
constructor(private contentAndStructureService: ContentAndStructureService) {}
ngOnInit() {
this.isLoading = true;
this.isProductLoading = true;
this.contentAndStructureService.getproducts({ category: 'dev' })
.pipe(finalize(() => { this.isProductLoading = false; }))
.subscribe(iproducts => this.iproducts = iproducts);
}
}
This is my HTML. It prints the value of the iproducts.id just fine.
<div class="container">
<mat-card>
<mat-card-content>
<mat-card-subtitle>
<app-loader [isLoading]="isProductLoading" size="1.5"></app-loader>
<q [hidden]="isProductLoading">{{iproducts.id}}</q>
</mat-card-subtitle>
</mat-card-content>
</mat-card>
</div>
BUT in the console the follow error gets logged
ERROR TypeError: Cannot read property 'id' of undefined
at Object.eval [as updateRenderer] (home.component.html:13)
at Object.debugUpdateRenderer [as updateRenderer] (core.js:14377)
at checkAndUpdateView (core.js:13513)
at callViewAction (core.js:13858)
at execComponentViewsAction (core.js:13790)
at checkAndUpdateView (core.js:13514)
at callViewAction (core.js:13858)
at execEmbeddedViewsAction (core.js:13816)
at checkAndUpdateView (core.js:13509)
at callViewAction (core.js:13858)
I dont understand how the id can be undefined and at the same time the value get printed just fine ... and i dont know how to fix it. I have spend countless hours on this and hope someone has time to show me what i do wrong here.
Upvotes: 0
Views: 58
Reputation: 2092
I think you have two problems. First is async. Heres a timeline of whats happening
iproducts.id
is calledsome time later......
So, when your view initializes and your template is run iproducts
is still null because your http request hasn’t finished yet. I would either wrap that part of the template in an if ngIf=“iproducts”
or give iproducts a default value that wont cause an error when properties are accessed.
The second issue is you have an array and your trying to access an id on it..... I think you want use an ngFor=“let iprod of iproducts”
to iterate the items in the array then say iprod.id
.
You’ll still need to either check to make sure iproducts
isn’t null or give it a default value of []
Upvotes: 1