Reputation: 31
I've created an angular 2 app which calls a restful api and When I use the below http get call in a service I am getting an error saying "NgFor only supports binding to Iterables such as Arrays."
This is my service.
@Injectable()
export class CategotyService {
private url = "http://myapi:9510/api/Category/getcatlist";
private headers = new Headers({ 'Content-Type': 'application/json', 'Token': '26714A2385448406BD76070255BAE45A41E890AF51DA173AC347A37DFF61A3254CCBE1BCA66493908262261ACBC63CF99DA986E963021FD87AC86C7652E3C2029476CCF0BE548B1FF87FC955ECEA9EE325C535A7B4BF7408236E379850241306' });
constructor(private _http: Http) { }
getProducts(): Observable<IApp[]> {
return this._http.get(this.url, { headers: this.headers }).map((response: Response) => <IApp[]>response.json()).do(data => console.log(data)).catch(this.handleError)
}
private handleError(error: Response) {
console.log(error)
return Observable.throw(error.json() || "server error")
}}
and this is the interface I've used
export interface IApp {
Data: {
"Id": number,
"CobjUId": string,
"Name": string,
"ShortCode": string,
" ObjectType": string,
"ParentId": string,
"OwnerId": string,
"CreatedBy": string,
"CreatedOn": Date,
"ModifiedBy": string,
"ModifiedOn": Date,
"IsPublic": boolean,
"IsDeleted": boolean,
"Status": string,
"Role": string
},
StatusCode: string,
Message: string
}
And contains this HTML...
<ul>
<li *ngFor="let Cat of Categories">
{{Cat.Id}}
</li>
</ul>
and the component is as follows...
export class AppComponent implements OnInit {
constructor(private _categotyService: CategotyService) {
}
errormessage: string;
ngOnInit(){
this._categotyService.getProducts().subscribe(res => this.Categories = res, error => this.errormessage = <any>error, () => console.log('done'));
}
Categories: IApp[];
}
this is the json output I'm recieving from the restful server..
Data:"[{"Id":0,"CobjUId":"DD8F81350E38411A9DD4F344770734FF","Name":"Network","ShortCode":"Net","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null},{"Id":0,"CobjUId":"81AB5E3E6BAE423ABE089CDF1BD17EEF","Name":"human resources","ShortCode":"hum","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null},{"Id":0,"CobjUId":"CC381BF9082541F894B5030800D8665D","Name":"Finance","ShortCode":"Fin","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null},{"Id":0,"CobjUId":"0139C0DDAE9D40E086B04E853FB0B885","Name":"Recruiting","ShortCode":"Rec","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null}]",Message:"Successfully retrieved",StatusCode:"Success 200"
I've tried addding .Data to
getProducts(): Observable<IApp[]> {
return this._http.get(this.url, { headers: this.headers }).map((response: Response) => <IApp[]>response.json().Data).do(data => console.log(data)).catch(this.handleError)
}
and changed my interface to
export interface IApp {
Id: number,
CobjUId: string,
Name: string,
ShortCode: string,
ObjectType: string,
ParentId: string,
OwnerId: string,
CreatedBy: string,
CreatedOn: Date,
ModifiedBy: string,
ModifiedOn: Date,
IsPublic: boolean,
IsDeleted: boolean,
Status: string,
Role: string }
then the error changed to
Cannot find a differ supporting object '[{"Id":0,"CobjUId":"DD8F81350E38411A9DD4F344770734FF","Name":"Network","ShortCode":"Net","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null},{"Id":0,"CobjUId":"81AB5E3E6BAE423ABE089CDF1BD17EEF","Name":"human resources","ShortCode":"hum","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null},{"Id":0,"CobjUId":"CC381BF9082541F894B5030800D8665D","Name":"Finance","ShortCode":"Fin","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null},{"Id":0,"CobjUId":"0139C0DDAE9D40E086B04E853FB0B885","Name":"Recruiting","ShortCode":"Rec","ObjectType":null,"ParentId":null,"OwnerId":null,"CreatedBy":null,"CreatedOn":null,"ModifiedBy":null,"ModifiedOn":null,"IsPublic":false,"IsDeleted":false,"Status":null,"Role":null}]' of type 'string'. NgFor only supports binding to Iterables such as Arrays.
I felt the problem lies with single quote present at the start of arrray. Please,provide me any approach whether to use a pipe or any other format to get rid of this error ..........
Answer
My error got resolved by calling this method in the map method
private extractData(res: Response) {
let body = JSON.parse(res.json().Data);
console.log(body);
return body;
}
Initially the json I recieved is being stringified, so the ngfor is unable to iterate it, so I've just parsed it and it worked perfectly.
Upvotes: 2
Views: 1017
Reputation: 3618
*ngFor in template accepts Array of Object
i.e Categories Variable contains Array of Object
Categories = [
{
"Id": 1,
"CobjUId": abc,
"Name": mad
},
{
"Id": 2,
"CobjUId": cde,
"Name": psd
}
]
Template
<ul>
<li *ngFor="let Cat of Categories">
{{Cat.Id}}
</li>
</ul>
Upvotes: 2
Reputation: 974
U need to map object to an array so you can ngFor it or go for this solution:
Upvotes: 0