67

Im following this tutorial. On the way to get list of users from api.github Im getting error:

Cannot find a differ supporting object '[object Object]'

I think its related to

 <ul>
 <li *ngFor = "#user of users">
 {{user | json}}
 </li>
 </ul>

In my code because before it there was no any error, and im unsure if data come from get request, just clicking didnt give any error, here is my code so far

@Component({
selector: 'router',
pipes : [],

template: `
<div>
<form [ngFormModel] = "searchform">
      <input type = 'text' [ngFormControl]= 'input1'/>
</form>
     <button (click) = "getusers()">Submit</button>
</div>
<div>
<ul>
    <li *ngFor = "#user of users">
    {{user | json}}
    </li>
</ul>
</div>
<router-outlet></router-outlet>
`,
directives: [FORM_DIRECTIVES]
})
export class router {
searchform: ControlGroup;
users: Array<Object>[];
input1: AbstractControl;

constructor(public http: Http, fb: FormBuilder) {
    this.searchform = fb.group({
        'input1': ['']
    })
    this.input1 = this.searchform.controls['input1']
}
getusers() {
    this.http.get(`https://api.github.com/
search/users?q=${this.input1.value}`)
        .map(response => response.json())
        .subscribe(
        data => this.users = data,
        error => console.log(error)
        )
}
}
bootstrap(router, [HTTP_PROVIDERS])
Jota.Toledo
  • 27,293
  • 11
  • 59
  • 73
blackHawk
  • 6,047
  • 13
  • 57
  • 100

8 Answers8

57

I think that the object you received in your response payload isn't an array. Perhaps the array you want to iterate is contained into an attribute. You should check the structure of the received data...

You could try something like that:

getusers() {
  this.http.get(`https://api.github.com/search/users?q=${this.input1.value}`)
    .map(response => response.json().items) // <------
    .subscribe(
      data => this.users = data,
      error => console.log(error)
    );
}

Edit

Following the Github doc (developer.github.com/v3/search/#search-users), the format of the response is:

{
  "total_count": 12,
  "incomplete_results": false,
  "items": [
    {
      "login": "mojombo",
      "id": 1,
      (...)
      "type": "User",
      "score": 105.47857
    }
  ]
}

So the list of users is contained into the items field and you should use this:

getusers() {
  this.http.get(`https://api.github.com/search/users?q=${this.input1.value}`)
    .map(response => response.json().items) // <------
    .subscribe(
      data => this.users = data,
      error => console.log(error)
    );
}
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • by doing this error didnt show also no user displayed, console.log is empty – blackHawk Feb 26 '16 at 20:07
  • You shoud use `items`. See this doc: https://developer.github.com/v3/search/#search-users for the format of the response payload. This corresponds to the array of users in the response payload... I updated my answer – Thierry Templier Feb 26 '16 at 20:18
  • 2
    For me the error happened because I had a template variable (e.g. `
    `) with the same name as the variable I was setting with data for the ngFor. So Angular was overriding my variable with the template variable. *facepalm*
    – Isaac Lyman Apr 02 '19 at 19:45
15

Missing square brackets around input property may cause this error. For example:

Component Foo {
    @Input()
    bars: BarType[];
}

Correct:

<app-foo [bars]="smth"></app-foo>

Incorrect (triggering error):

<app-foo bars="smth"></app-foo>

mp31415
  • 6,531
  • 1
  • 44
  • 34
  • I lost an hour because of this! - Thanks! – James Poulose Dec 07 '19 at 18:23
  • A special case: Running some karma tests for my application, I got this error when setting styles in the template directly on primeng components. Putting the style in a `` around the component solved it. When running the application itself, the error did not show at all. – user11883568 Dec 06 '22 at 11:32
14

I received this error in my code because I'd not run JSON.parse(result).

So my result was a string instead of an array of objects.

i.e. I got:

"[{},{}]" 

instead of:

[{},{}]

import { Storage } from '@ionic/storage';
...
private static readonly SERVER = 'server';
...
getStorage(): Promise {
  return this.storage.get(LoginService.SERVER);
}
...
this.getStorage()
  .then((value) => {
     let servers: Server[] = JSON.parse(value) as Server[];
                   }
  );
JGFMK
  • 8,425
  • 4
  • 58
  • 92
7

Something that has caught me out more than once is having another variable on the page with the same name.

E.g. in the example below the data for the NgFor is in the variable requests. But there is also a variable called #requests used for the if-else

<ng-template #requests>
  <div class="pending-requests">
    <div class="request-list" *ngFor="let request of requests">
      <span>{{ request.clientName }}</span>
    </div>
  </div>
</ng-template>
Kildareflare
  • 4,590
  • 5
  • 51
  • 65
7

This ridiculous error message merely means there's a binding to an array that doesn't exist.

<option
  *ngFor="let option of setting.options"
  [value]="option"
  >{{ option }}
</option>

In the example above the value of setting.options is undefined. To fix, press F12 and open developer window. When the the get request returns the data look for the values to contain data.

If data exists, then make sure the binding name is correct

//was the property name correct? 
setting.properNamedOptions

If the data exists, is it an Array?

If the data doesn't exist then fix it on the backend.

JWP
  • 6,672
  • 3
  • 50
  • 74
  • Solved my issue not being able to loop through Wordpress tag id data, which was in the form of`[...{"tags": [2,3,4],}...]` – aleksejjj Dec 25 '21 at 18:22
1

If this is an Observable being return in the HTML simply add the async pipe

    observable | async
Victor
  • 59
  • 6
0

Explanation: You can *ngFor on the arrays. You have your users declared as the array. But, the response from the Get returns you an object. You cannot ngFor on the object. You should have an array for that. You can explicitly cast the object to array and that will solve the issue. data to [data]

Solution

getusers() {
    this.http.get(`https://api.github.com/
search/users?q=${this.input1.value}`)
        .map(response => response.json())
        .subscribe(
        data => this.users = [data], //Cast your object to array. that will do it.
        error => console.log(error)
        )
0

If you don't have an array but you are trying to use your observable like an array even though it's a stream of objects, this won't work natively. I show how to fix this below.

If you are trying to use an observable whose source is of type BehaviorSubject, change it to ReplaySubject then in your component subscribe to it like this:

Component

this.messages$ = this.chatService.messages$.pipe(scan((acc, val) => [...acc, val], []));

Html

<div class="message-list" *ngFor="let item of messages$ | async">
Post Impatica
  • 14,999
  • 9
  • 67
  • 78