Reputation: 8431
I looked at similar questions, but none of them helped me. I am going to receive an object like the following:
[
{
"id": 1,
"name": "Safa",
"email": "[email protected]",
"purpose": "thesis",
"programme": "Software Engineering",
"year": 2016,
"language": "Estonian",
"comments": "In need of correcting a dangling participle.",
"status": "RECEIVED"
},
{
"id": 2,
"name": "Safa",
"email": "[email protected]",
"purpose": "thesis",
"programme": "Software Engineering",
"year": 2016,
"language": "Estonian",
"comments": "In need of correcting a dangling participle.",
"status": "RECEIVED"
},
{
"id": 3,
"name": "Salman",
"email": "[email protected]",
"purpose": "thesis",
"programme": "Software Engineering",
"year": 2016,
"language": "Estonian",
"comments": "In need of correcting a dangling participle.",
"status": "RECEIVED"
}
]
and here is my http service to receive it:
getRequest(){
return this._http.get("http://consultationwebserver.herokuapp.com/requests").map(res => res.json());
}
and finally, in the i called the service in this way:
requests;
constructor(private _http:requestService){}
ngOnInit(){
this.requests=this._http.getRequest().subscribe(res=>this.requests=res);
}
Unfortunately, when the page loads it complains with:
Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
So, what is going wrong with this code?
Upvotes: 93
Views: 383185
Reputation: 136194
There you don't need to use this.requests=
when you are making get
call(then requests
will have observable subscription). You will get a response in observable success
so setting requests
value in success make sense(which you are already doing).
this._http.getRequest().subscribe(res=>this.requests=res);
If it still shows an error related to type, add any
/RelevantModel
type on subscribe parameter object.
this._http.getRequest().subscribe(
(res: any[]) => this.requests =res
);
Basically, *ngFor works for only iterable items like arrays. If you assign this.requests
to have an object value, and you're trying to use *ngfor it will return this error.
For example, when you declare array like this.myArray = {}
this problem will occur. It should be this.myArray = []
.
Using async
pipe with requests$
as observable stream.
private _http = inject(HttpClient);
requests$ = this._http.getRequest();
HTML
<ng-container *ngFor="let request of requests$ | async">
{{ request.name }}
</ng-container>
Using async
pipe with requests$
as observable stream.
private _http = inject(HttpClient);
requests = toSignal(this._http.getRequest());
HTML
@for(request of requests()) {
{{ request.name }}
}
Using async
pipe with requests$
as observable stream.
private _http = inject(HttpClient);
requests = resource({
loader: () => this._http.getRequest(),
})
requests = toSignal(this._http.getRequest());
HTML
@for(request of requests()) {
{{ request.name }}
}
Upvotes: 47
Reputation: 307
You can also change how you access the property. I faced this issue and instead of accessing :
this.someService.details
I've used :
this.someService['details'];
This fixed this error for me.
Upvotes: 0
Reputation: 3386
I don't know if someone would get the same thing as me, and I have no idee why this happens (maybe is a bug?), but I actually had this error because only because we were trying to create a ComponentPortal for an angular overlay like this:
const smartfillPortal = new ComponentPortal(
SmartFillModalComponent,
this.viewContainerRef,
{
get: () => this.smartfillOverlayRef,
}
);
changing it to
const smartfillPortal = new ComponentPortal(SmartFillModalComponent);
fixed it for some reason (I am guessing I am also missing some info about overlays?).
The weird thing is that even something like this in the overlay code:
<div class="flex" *ngFor="let i of [1,2,3]; let i = index">
<span>hi there</span>
</div>
would result in
Error: Cannot find a differ supporting object '1,2,3' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
Upvotes: 0
Reputation: 1
For me the error was resolved when I added the index to *ngFor.
<tr *ngFor = "let element of element_list; let i=index">
<td>{{element.id}}</td>
<td>{{element.status}}</td>
<td>{{element.name}}</td>
</tr>
Upvotes: -1
Reputation: 122
Store that objects into Array and then iterate the Array
export class AppComponent {
public obj: object =null;
public myArr=[];
constructor(){
this.obj = {
jon : {username: 'Jon', genrePref: 'rock'},
lucy : {username: 'Lucy', genrePref: 'pop'},
mike : {username: 'Mike', genrePref: 'rock'},
luke : {username: 'Luke', genrePref: 'house'},
james : {username: 'James', genrePref: 'house'},
dave : {username: 'Dave', genrePref: 'bass'},
sarah : {username: 'Sarah', genrePref: 'country'},
natalie : {username: 'Natalie', genrePref: 'bass'}
}
}
ngOnInit(){
this.populateCode();
}
populateCode(){
for( let i in this.obj) { //Pay attention to the 'in'
console.log(this.obj[i]);
this.myArr.push(this.obj[i]);
}
}
}
<div *ngFor="let item of myArr ">
{{item.username}}
{{item.genrePref}}
</div>
Upvotes: 0
Reputation: 11
Here is the solution.
When you are receiving array from your database. and you are storing array data inside a variable but the variable defined as object. This time you will get the error.
I am receiving array from database and I'm stroing that array inside a variable 'bannersliders'. 'bannersliders' type is now 'any' but if you write 'bannersliders' is an object. Like bannersliders:any={}. So this time you are storing array data inside object type variable. So you find that error.
So you have to write variable like 'bannersliders:any;' or 'bannersliders:any=[]'.
Here I am giving an example.
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
bannersliders:any;
getallbanner(){
this.bannerService.getallbanner().subscribe(data=>{
this.bannersliders =data;
})
}
Upvotes: 1
Reputation: 131
You can declare the books (on line 2) as an array:
title: any = 'List of books are represted in the bookstore';
books: any = [];
constructor(private service: AppService){
}
ngOnInit(){
this.getBookDetails();
}
getBookDetails() {
this.service.getBooks().subscribe(books => {
this.books = books.json();
console.log(this.books);
});
}
Upvotes: 12
Reputation: 807
*********** PARSE THE RESULT TO JSON OBJECT: JSON.prase(result.arrayOfObjects) ***********
I came to this page after I faced this issue. So, my issue was that the server is sending array of objects in the form of string. It is something like this:
when I printed result on console after getting from server it is string:
'arrayOfObject': '[
{'id': '123', 'designation': 'developer'},
{'id': '422', 'designation': 'lead'}
]'
So, I have to convert this string to JSON after getting it from server. Use method for parsing the result string that you receive from server:
JSON.parse(result.arrayOfObjects)
Upvotes: 0
Reputation: 834
For anyone else with this issue that arrives here via Google, please check that the host element of the *ngFor
directive is accurate. By this, I mean that I encountered this error and spent a long time researching fixes before realizing that I had put the *ngFor
on an ng-template
element instead of on my component I wanted to repeat.
Incorrect
<ng-template *ngFor=let group of groups$ | async" ...>
<my-component [prop1]="group.key" ... </my-component>
<\ng-template>
Correct
<my-component *ngFor=let group of groups$ | async" [prop1]="group.key" ... </my-component>
I know this is an obvious mistake in hindsight, but I hope an answer here will save someone the headache I now have.
Upvotes: 4
Reputation: 37
Just declare the var as an array in which you holding the data , it worked for me.
listingdata:Array<any> = [];
this.listingdata = data.results.rows;
and loop the listingdata on html page
Upvotes: 1
Reputation: 31
You should use async pipe. Doc: https://angular.io/api/common/AsyncPipe
For example:
<li *ngFor="let a of authorizationTypes | async"[value]="a.id">
{{ a.name }}
</li>
Upvotes: 3
Reputation: 17
In you use spring boot with Angular ; make sure that whether you create default
Upvotes: 0
Reputation: 61
<ul>
<li *ngFor = "let Data of allDataFromAws | async">
<pre> {{ Data | json}}</pre>
</li>
</ul>
use async to convert allDataFromAws into Array Object....
Upvotes: 1
Reputation: 506
To iterate over an object which has a json format like below
{
"mango": { "color": "orange", "taste": "sweet" }
"lemon": { "color": "yellow", "taste": "sour" }
}
Assign it to a variable
let rawData = { "mang":{...}, "lemon": {...} }
Create a empty array(s) for holding the values(or keys)
let dataValues = []; //For values
let dataKeys = []; //For keys
Loop over the keys and add the values(and keys) to variables
for(let key in rawData) { //Pay attention to the 'in'
dataValues.push(rawData[key]);
dataKeys.push(key);
}
Now you have an array of keys and values which you can use in *ngFor or a for loop
for(let d of dataValues) {
console.log("Data Values",d);
}
<tr *ngFor='let data of dataValues'> ..... </tr>
Upvotes: 4
Reputation: 5023
this.requests=res
here you are trying to assign following response to object,
{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK",
"url":"xyz","ok":true,"type":4,"body":[{}]}
Since, object format is different then response format you have to assign res.body
part from your response to get required contents.
Upvotes: 1
Reputation: 2490
i have the same problem. this is how i fixed the problem. first when the error is occurred, my array data is coming form DB like this --,
{brands: Array(5), _id: "5ae9455f7f7af749cb2d3740"}
make sure that your data is an ARRAY, not an OBJECT that carries an array. only array look like this --,
(5) [{…}, {…}, {…}, {…}, {…}]
it solved my problem.
Upvotes: 3
Reputation: 6788
i have faced same problem
my initial json
{"items":
[
{"id":1,
"Name":"test4"
},
{"id":2,
"Name":"test1"
}
]
}
i have changed my json inside []
[{"items":
[
{"id":1,
"Name":"test4"
},
{"id":2,
"Name":"test1"
}
]
}]
Upvotes: 2
Reputation: 718
My solution is create a Pipe for return the values array or propierties object
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'valueArray',
})
export class ValueArrayPipe implements PipeTransform {
// El parametro object representa, los valores de las propiedades o indice
transform(objects : any = []) {
return Object.values(objects);
}
}
The template Implement
<button ion-item *ngFor="let element of element_list | valueArray" >
{{ element.any_property }}
</button>
Upvotes: 10
Reputation: 81
In your JSOn file, please make below change.
{
"data":
[
{
"id": 1,
"name": "Safa",
"email": "[email protected]",
"purpose": "thesis",
"programme": "Software Engineering",
"year": 2016,
"language": "Estonian",
"comments": "In need of correcting a dangling participle.",
"status": "RECEIVED"
},
{
"id": 2,
"name": "Safa",
"email": "[email protected]",
"purpose": "thesis",
"programme": "Software Engineering",
"year": 2016,
"language": "Estonian",
"comments": "In need of correcting a dangling participle.",
"status": "RECEIVED"
},
{
"id": 3,
"name": "Salman",
"email": "[email protected]",
"purpose": "thesis",
"programme": "Software Engineering",
"year": 2016,
"language": "Estonian",
"comments": "In need of correcting a dangling participle.",
"status": "RECEIVED"
}
]
}
And after that:
this.http.get(url).map(res:Response) => res.json().data);
The data is actually the name of tge collection of json file. Please try the code above, I am sure it will work.
Upvotes: 7
Reputation: 658263
Remove this.requests
from
ngOnInit(){
this.requests=this._http.getRequest().subscribe(res=>this.requests=res);
}
to
ngOnInit(){
this._http.getRequest().subscribe(res=>this.requests=res);
}
this._http.getRequest()
returns a subscription, not the response value.
The response value is assigned by the callback passed to subscribe(...)
Upvotes: 19
Reputation: 253
I had the same error because I have mapped the HTTP response like this:
this.http.get(url).map(res => res.json);
Note how I accidentally called .json like a variable and not like a method.
Changing it to:
this.http.get(url).map(res => res.json());
did the trick.
Upvotes: 7