I'm having difficulty overcoming the "Cannot find a differ supporting object '[object Object]' of type 'object'" error that seems to be really common with Angular2, and I'm hoping someone has encountered something similar.
Here's the (anonymized) JSON coming from my service, which is really simple:
[
{
"item_id": 1,
"item_type": 2,
"item_name": "Item 1",
"item_description": "First item"
},
{
"item_id": 2,
"item_type": 4,
"item_name": "Item 2",
"item_description": "Second item"
}
]
And here's the contents of my class, service, and component that describes these objects:
// item.ts
export class Item {
item_id: number;
item_type: number;
item_name: string;
item_description: string;
}
//item.service.ts snippet
getItems(): Promise<Item[]> {
return this.http.get('http://apiurl', { withCredentials: true })
.toPromise()
.then((response) => {
let body = response.json();
return body as Item[];
})
.catch(this.handleError);
}
//item.component.ts snippet
items: Item[];
getItems(): void { // Function that calls the item service
this.itemService
.getItems()
.then((items) => {
console.log(items); // I use this to verify that I'm getting an array.
this.items = items;
});
}
And finally, the ngFor component:
<ul>
<li *ngFor="let item of items">
<i class="fa fa-database"></i> {{item.item_name}}
</li>
</ul>
I'm not seeing anything wrong with any part of this. The retrieved data definitely does reach the item component, which means my imports are correct, and what shows up in my console.log is definitely an array, with the __proto__:Array[0]
property and everything. It even looks identical to what gets output if I console log the Angular tutorial Heroes app. Yet it simply will not iterate over the array, insisting that it's an object.
What am I doing wrong? Is ngFor just broken?
Edit Here is the complete (anonymized) class, with unrelated bits removed:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Headers, Response, Http, RequestOptions } from '@angular/http';
import { Item } from '../../classes/item/item';
import { ItemService } from '../../services/item/item.service';
@Component({
moduleId: module.id,
selector: 'my-items',
templateUrl: 'items.component.html'
})
export class ItemComponent implements OnInit {
items: Item[] = [];
constructor(
private router: Router,
private itemService: ItemService
) { }
getItems(): void {
console.log(this.items);
this.itemService
.getItems()
.then((items) => {
console.log(items);
this.items = Array.from(items);
});
}
ngOnInit() {
this.getItems();
}
}
Edit 2:
I got it! And I think it might be a bug in Angular2. Above, I sanitized my code by using a generic variable name called "items." But in the real, production code, the variable is called "entities." And for the whole time, I've had it named like that. On a whim, I changed the name of the variable to "testentities," and it worked!
So just to make sure, I tested with multiple variations, and it worked every time. Then I changed it back to "entities," and the error reappeared. It seems to be a reserved variable of some kind.
I'll rigorously test this out, and if it is consistently reproducible, I'll report it on the bug tracker.
Give this a try
item.service.ts snippet
getItems(): Promise<Item[]> {
return this.http.get('http://apiurl', { withCredentials: true })
.toPromise()
.then((response) => {
let body = response.json();
return body;
})
.catch(this.handleError);
}
item.component.ts snippet
items: Item[] = []; // For whatever reason it thinks this is an Object
getItems(): void { // Function that calls the item service
//this.items = Array.from(this.items);
this.itemService.getItems().then(items => this.items = items);
}
Alight, you have exhausted my debugging resources, so I will take it to the basics,
Angular 2 HTTP Client is where they show you how to make a GET
request. Then HERE is the Promise based setup.
So going off of that this is what yours should look like.
item.service.ts snippet
getItems(): Promise<Item[]> {
return this.http.get('http://apiurl', { withCredentials: true })
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
private handleError (error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Promise.reject(errMsg);
}
item.component.ts
items: Item[] = [];
getItems(): void {
this.itemService.getItems().then(items => this.items = items);
}
It sounds like the OP figured out his problem and it had to do with the name of one of the variables, it would appear that a variable named entites
could cause Angular 2 to break.
"But in the real, production code, the variable is called "entities." And for the whole time, I've had it named like that. On a whim, I changed the name of the variable to "testentities," and it worked!
So just to make sure, I tested with multiple variations, and it worked every time. Then I changed it back to "entities," and the error reappeared."
entities: any{};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With