Lijin Durairaj
Lijin Durairaj

Reputation: 3501

How to bind dropdown asynchronously in angular2 using observables?

I am new to angular2 and i wonder how to bind drop down asynchronously using angular2? I have a service like this

 this.http.get('http://172.17.40.41:8089/api/Master/GetAllCountry')
            .subscribe(value => {
                var results = JSON.parse(value['_body']);
                for (let d of results) {
                    this.countries.push(new Country(d['Country'], d['CountryCode']))
                }
            }, error => error, () => {
                console.log('complete');
                return this.countries;

            });

and i am calling the service from the component like this

this.countries = this.countryServices.getCountry();

Now when i am trying to bind the data in the dropdown, i am not able to bind it

    <select class="form-control input-sm" formControlName="country">                                               
    <option class="small" *ngFor="let c of countries" value="{{c.countryCode}}">{{c.countryName}}</option> 
</select>

I also tried to use the keyup event of angular2 like this (keyup)="0" but it never worked.

Upvotes: 3

Views: 4822

Answers (1)

redevill
redevill

Reputation: 21

I came across your question while trying to find an answer to it.

It was not clear to me that your service is returning an observable. Here is my solution if it helps someone, after all this time:

First this service gets data from a firebase database and converts to a custom interface, returning this as an observable. In a real service an error handler should be included.

import {Injectable} from "@angular/core";
import {AngularFireDatabase} from "angularfire2/database/database";
import {IkeyName, KeyValPair} from "interfaces/IkeyName";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/map';

@Injectable()
export class SelectLists {
private rootRef = this.db.database.ref();

constructor(public db: AngularFireDatabase) {}

getAllOrgs(): Observable<IkeyName[]> {
var companyKeys = this.rootRef.child('organization');

return Observable.fromPromise(companyKeys.once("value")).map((data) => {
     var kps: IkeyName[] = [];

     for (let orgKey of Object.keys(data.val())){
       //Custom translation of database data to Your interface
       var kp = new KeyValPair();
       kp.Id = data.val().databaseId
       kp.Name = data.val().databaseNameValue
       kps.push(kp);
     }
     return kps;

 });

Next, in the component class we inject the service and call it.

export class GrowerReceiptComponent implements OnInit {
 public orgList : Observable<IkeyName[]>;
 public selectedOrg : IkeyName;

 constructor(public selLists: SelectLists) {
   this.orgList = selLists.getAllOrgs();
 }

 ngOnInit() {}
}

... And finally bind this observable value to the drop down view Please note: 1. The observable is subscribed in the view with the | ansync 2. The selected item is bound to the whole object, not just a value property 3. The viewable portion is kept to only the name part of the object.

<select class="form-control" required [(ngModel)]="selectedOrg" >
    <option *ngFor="let org of orgList | async" [ngValue]="org">{{org.Name}}</option>
</select>

Hope This helps

Upvotes: 2

Related Questions