0

I've been following the Tour of Heroes chapter on http calls and am trying to implement something similar with a different API. However, I get the following error:

Cannot find a differ supporting object '[object Object]' of type 'Bond Street 1'. NgFor only supports binding to Iterables such as Arrays.

Any clues on why this is?

My service looks as follows and works when I console.log the result

  search(stationNumber: number): Observable<BikeStand[]> {
    return this.http.get(`APIURL${stationNumber}`)
      .map((b: Response) => {
        console.log(b.json() as BikeStand[])
        return b.json() as BikeStand[];
      });
  }

My component looks as follows

export class BikestandSearchComponent implements OnInit {

  bikestands: Observable<BikeStand[]>;
  private searchTerms = new Subject<number>();

  constructor(private bikestandSearchService: BikestandSearchService) { }

  search(term: number): void {
    this.searchTerms.next(term);
  }

  ngOnInit(): void {
    this.bikestands = this.searchTerms
      .debounceTime(300)
      .distinctUntilChanged()
      .switchMap(term => term ? this.bikestandSearchService.search(term) : Observable.of<BikeStand[]>([]))
      .catch(error => {
        console.log(error);
        return Observable.of<BikeStand[]>([])
      })
  }

And my view likes this

<div id="search-component">
  <h4>Bikestand search</h4>
  <input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
  <div *ngFor="let bikestand of bikestands | async">{{bikestand.name}}</div>
</div>

My api for a given key looks as follow FYI

{
number: 1,
name: "Bond Street 1",
address: "Street",
position: {
lat: 55.340962,
lng: -6.3
},
banking: false,
bonus: false,
status: "OPEN",
contract_name: "City",
bike_stands: 29,
available_bike_stands: 19,
available_bikes: 10,
last_update: 1473356300000
}

2 Answers 2

1

It looks like your service or HTTP request isn't actually sending an array, it is sending a single Object. For example, I ran this code:

import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <p *ngFor="let bike of bikestand">{{bike.name}}</p>
    </div>
  `,
})
export class App {

  bikestand:any = {
    number: 1,
    name: "Bond Street 1",
    address: "Street",
    position: {
      lat: 55.340962,
      lng: -6.3
    },
    banking: false,
    bonus: false,
    status: "OPEN",
    contract_name: "City",
    bike_stands: 29,
    available_bike_stands: 19,
    available_bikes: 10,
    last_update: 1473356300000
  };

  constructor() {
    this.name = 'Angular2'
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}`

And got the same error. But change bikestand to an actual array (by putting square brackets around it) and I get correct result.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks both. As you mentioned changing return b.json() as BikeStand[]; to return [b.json()] as BikeStand[]; in my service fixes the problem. I'm surprised though that casting it as BikeStand[] doesn't automatically transform the output into an array
Casting doesn't do a conversion, you are just telling TypeScript 'trust me, this method returns any but I know what is inside is Bikestand[], so please treat it like that.'
1

as the error states, you are trying to iterate over an object using *ngFor rather than an array. the api you are using/returned is an object.

Check if console.log(b.json() as BikeStand[]) returns an objects which has some data property. if true then

return b.json().data instead .

we want to extract array out of the object to iterate over.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.