Search code examples
angularobservableiterablebootstrap-selectngfor

NgFor only supports binding to Iterables & Bootstrap-Select-Box is empty


SOLUTION:

We have solved 2 Problems here:

1) Wrong assignment with httpt.get, we have got the error message:

ORIGINAL EXCEPTION: Cannot find a differ supporting object 
'[object Object]' of type 'object'. 
NgFor only supports binding to Iterables such as Arrays.

2) Timing problem with Bootstrap-Select-Box; option-fields are empty

1) WRONG ASSIGNMENT

Following assignment is wrong:

this.agency = this.ws.get(serviceUrls.agency)
  .subscribe(
    (data:any) => this.agency = data,
    (err:any) => console.debug('AGENCY ERROR:',err),
    () => console.debug(this.agency)
  );

and gives the output:

[Object, Object, Object, Object,..]

enter image description here

what is not iterable via ngFor and should be corrected into:

this.ws.get(serviceUrls.agency)
  .subscribe(
    (data:any) => **this.agency = data**,  // <-- ONLY HERE
    (err:any) => console.debug('AGENCY ERROR:',err),
    () => console.debug(this.agency)
  );

For the sake of completeness, this is ws.get-method:

get(url: string) {
    return this.http.get(url)
      .map((data:any) => data.json());
  }

and this is the agency:

agency: any[];

2) TIMING PROBLEM WITH BOOTSTRAP-SELECT & ANGULAR2

That is the Bootstrap-Select-Box (a little bit - regarding CI - adapted version):

<select [(ngModel)]="localValues.agency"
        name="agency"
        id="agency"
        class="selectpicker select-search"
        data-selectpicker
        data-live-search="true"
        required="">
  <option
    *ngFor="let item of agency"
    [ngValue]="item.value">
    {{ item.label }}
  </option>
</select>

The activating of selectpicker happens in:

  ngAfterViewChecked () {
    //noinspection TypeScriptUnresolvedFunction
    $('.selectpicker').selectpicker();
  } 

But an importang thing was missing; the select-box was rendered before the observables emit data. Therefore we have to check the existence of agency before and then render the box:

ngAfterViewChecked () {
    if (this.agency) {  // <-- IMPORTANT!
      //noinspection TypeScriptUnresolvedFunction
      $('.selectpicker').selectpicker();
    }
}

That's all! Maybe this information is useful for you too ;)


Solution

  • You put Subscription object by writing this.agency = this.ws.get(serviceUrls.agency) into variable agency. Don't do that. Leave it for you success function. Just remove this.agency =. Or! You can use async pipe but remove your success callback.

    You have problems with bootstrap-select because of [value] property. See here. So you should use [ngValue]. And one more thing, you are trying to the selectpicker when you actually have no data, but if you wrap the init into check for this.agency existance it will work.