问题
when fetching json array object from rest api and trying to display in ngfor failed with the reason
error
EXCEPTION: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays. in [indexes in HomeComponent@5:37]
Code
import {Component} from 'angular2/core';
import {HomeService} from './home.services';
import {Index} from './index';
@Component({
selector: 'home-app',
providers: [HomeService],
template: `
<section class="left_side">
<article>
<div class="div_home">
<div class="div_homeIndxPartition">
<div class="div_IndxPartition" *ngFor="#indObj of indexes">
<table width="500px" class="idx_cons_table_det">
<tr>
<th align="center" color="#A9F5F2"><h3>{{indObj.name}} ({{indObj.tracker}})</h3></th>
<th align="center">Value</th>
<th align="center">Change</th>
<th align="center">%</th>
</tr>
<tr>
<td align="center" colspan="1"></td>
<td align="center">{{indObj.value}}</td>
<td align="center">{{indObj.change}}</td>
<td align="center">{{indObj.percent}}%</td>
</tr>
</table>
<br/>
<table width="500px" class="idx_cons_table">
<tr>
<th align="center">High</th>
<th align="center">Low</th>
<th align="center">Open</th>
<th align="center">Close</th>
<th align="center">52 Week High</th>
<th align="center">52 Week Low</th>
</tr>
<tr>
<td align="center">{{indObj.high}}</td>
<td align="center">{{indObj.low}}</td>
<td align="center">{{indObj.open}}%</td>
<td align="center">{{indObj.close}}</td>
<td align="center">{{indObj.yearHigh}}</td>
<td align="center">{{indObj.yearLow}}%</td>
</tr>
</table>
</div>
</div>
</div>
</article>
</section>
`
})
export class HomeComponent {
public indexes:Array<Index>=[];
public error;
constructor(private _service: HomeService){
this.indexes = _service.getIndexes().subscribe(
data => this.indexes = JSON.parse(data),
error => alert(" Error is : " + error),
()=> console.log("finished")
);
console.log(this.indexes);
}
}
JSON Data
[
{
"id": 1,
"name": "FTSE 100",
"ticker": "UKX",
"value": 69875.23,
"change": 100,
"percent": 2.3,
"high": 69875.23,
"low": 69700.89,
"yearHigh": 699999.23,
"yearLow": 680005.23,
"open": 69600.54,
"close": 699000.97,
"constituents": null,
"runDate": "21/04/2015"
},
{
"id": 2,
"name": "FTSE 250",
"ticker": "MCX",
"value": 465820.85,
"change": 100,
"percent": 2.3,
"high": 465880.12,
"low": 465810.74,
"yearHigh": 478990.34,
"yearLow": 465320.23,
"open": 69600.54,
"close": 699000.97,
"constituents": null,
"runDate": "21/04/2015"
},
{
"id": 3,
"name": "FTSE All-Share",
"ticker": "ASX",
"value": 236549.23,
"change": 100,
"percent": 2.3,
"high": 236949.23,
"low": 236149,
"yearHigh": 246949.21,
"yearLow": 235549.29,
"open": 236519.23,
"close": 236649.23,
"constituents": null,
"runDate": "21/04/2015"
},
{
"id": 4,
"name": "Euro Stoxx 50",
"ticker": "STOXX50E",
"value": 123469.87,
"change": 100,
"percent": 2.3,
"high": 123499.87,
"low": 123439.87,
"yearHigh": 123499.87,
"yearLow": 123169.87,
"open": 123465.87,
"close": 123459.87,
"constituents": null,
"runDate": "21/04/2015"
},
{
"id": 5,
"name": "S&P 500 ",
"ticker": "S500",
"value": 358976.36,
"change": 100,
"percent": 2.3,
"high": 358986.36,
"low": 358946.36,
"yearHigh": 359976.36,
"yearLow": 357976.36,
"open": 358970.36,
"close": 358996.36,
"constituents": null,
"runDate": "21/04/2015"
},
{
"id": 6,
"name": "Dow Jones I.A.",
"ticker": "INDU",
"value": 456789.36,
"change": 100,
"percent": 2.3,
"high": 456799.36,
"low": 456779.36,
"yearHigh": 456889.36,
"yearLow": 456689.36,
"open": 456729.36,
"close": 456779.36,
"constituents": null,
"runDate": "21/04/2015"
},
{
"id": 7,
"name": "GOLD",
"ticker": "",
"value": 500,
"change": 100,
"percent": 2.3,
"high": 700,
"low": 300,
"yearHigh": 1500,
"yearLow": 350,
"open": 450,
"close": 470,
"constituents": null,
"runDate": "21/04/2015"
},
{
"id": 8,
"name": "Brent Crude",
"ticker": "",
"value": 112,
"change": 100,
"percent": 2.3,
"high": 115,
"low": 107,
"yearHigh": 200,
"yearLow": 72,
"open": 110,
"close": 115,
"constituents": null,
"runDate": "21/04/2015"
}
]
回答1:
I think that the value you set in the indexes
property isn't an array but an object.
I would see several reasons for this:
You receive the response instead of the payload from the
getIndexes
method. In this case, you could use themap
operator in this method:getIndexes() { return this.http.get(...).map(res => res.json()); }
The received payload doesn't correspond to an array but some of its properties. In this case, you need to set this property into the
indexes
property.
If you want to iterate over the properties of an object, you need to implement a custom filter like this:
@Pipe({name: 'keyValues'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]);
}
return keys;
}
}
and use it like that:
<div class="div_IndxPartition" *ngFor="#indObj of indexes | keyValues">
(...)
</div>
See this question:
- How to display json object using *ngFor
回答2:
You should try this:
In html:
<div *ngFor="let subsciption of subscriptions;">
<div class="col-md-6">
<h5 class="widget-title">{{subsciption.name}}</h5>
</div>
</div>
in .ts file:
export class SubscriptionComponent implements OnInit {
private subscriptions: any =[];
// private subscriptions: any ={}; // here dont use {}
.
.
.
.
.
getAllSubscriptions(queryString) {
this._http.get(`${environment.base_url}/subscriptions` + queryString)
.subscribe((response: Response) => {
this.subscriptions = response.json();
},
(error: Response) => {
console.log("Login error");
});
}
this.getAllSubscriptions(query);
}
回答3:
I had same problem and my solution was without Pipes. I did not use variable in the template that returns Observer, create intermediate variable and assign result to it. For example, we will save stream to this.sub
but result will save to this.indexes
on success callback and will use this variable in the html template.
@Component({
template: `
<ul>
<li *ngFor="let index of indexs">
{{ index }}
</li>
</ul>
`
})
export class HomeComponent {
privat sub;
public indexes:Array<Index>=[];
public error;
constructor(private _service: HomeService) {
this.sub = this._service.getIndexes().subscribe(
data => this.indexes = JSON.parse(data),
error => alert(" Error is : " + error),
() => console.log("finished")
);
}
}
回答4:
You don't want to use pipes when working with Observables. This error is very generic and the best way is to throw in a console.log() and see where you are going wrong as it could be numerous things.
My problem was my Array was inside the Object, and I was trying to loop over the Object. Other problems could include the mapping or the ngFor. My console output would look something like this:
this.indexes = _service.getIndexes()
.subscribe(
data => {
this.indexes = JSON.parse(data);
console.log(indexes);
},
error => alert(" Error is : " + error),
()=> console.log("finished")
);
console.log(this.indexes);
So the fix I needed was something like this:
this.indexes = _service.getIndexes()
.subscribe(
data => {
this.myNewObject = JSON.parse(data);
this.indexes = this.myNewObject.indexes;
},
error => alert(" Error is : " + error),
()=> console.log("finished")
);
console.log(this.indexes);
This was because the array was nested inside the Object, so I just created a new object and accessed the array by getting its property.
回答5:
i see your answer, and the easy way to solve is just set the type of the object in the *ngFor to array like this:
public indexes:Array<TYPE_OF_YOUR_DATA>=[];
来源:https://stackoverflow.com/questions/36839223/error-display-in-ngfor-json-array-object