Search code examples
angularangular2-formsangular2-directivesangular-directivengfor

Dynamic Select Option isn't binding Angular 2+


I'm developing a select option dependent of another one. In this case, the user select the country and after the cities of this country is loaded. I've looked some examples on the internet but it still doesn't work. The first select option works well, thats mean, the list of countries appears correctly. But the second one, when I select a specific country, doesn't show the related cities.

View code:

<div class="input-field col s6 m3 l3">
    <select materialize="material_select" formControlName="country" (change)="selectCity($event.target.value)">
        <option value="0" disabled selected>Country</option>
        <option *ngFor="let c of countries" value={{c.id}}>{{c.name}}</option>
      </select>
      <label>Country</label>
</div>

<div class="input-field col s6 m3 l3">
    <select materialize="material_select" formControlName="city">
        <option value="0" disabled selected>city</option>
        <option *ngFor="let ci of cities" value={{ci.id}}>{{ci.name}}</option>
      </select>
      <label>City</label>
</div>

The component code, summarized:

countries = any[];
countrySelected = any;
cities = any[];

this.placeService.getPlaces().subscribe(data => this.countries = data);


  selectCity(value) {
    this.countrySelected= this.countries.find(o => o.id === value);    
    this.cities= this.countrySelected.city;  
  }

The method located in the service:

  getPlaces() {
    return this.http.get('assets/database/rac/places.json')
    .map( (res: Response) => res.json().country);
  }

Finally, the JSON file which is called:

{
"country": 
[{
    "id": "1",
    "name": "Brazil",
            "city": [ { "id": "1", "name": "Rio Branco"}, 
                      { "id": "2", "name": "Xapuri"}, 
                      { "id": "3", "name": "Cruzeiro do Sul"} ] 
},
{
    "id": "2",
    "name": "Argentina",
            "city": [ { "id": "4", "name": "Buenos Aires"}, 
                      { "id": "5", "name": "Cordoba"}, 
                      { "id": "6", "name": "Rosario"} ] 
}]

Solution

  • If you're using angular2-materialize, I believe you need to add the directive materializeSelectOptions, otherwise materialize doesn't track changes to options:

    <select materialize="material_select" formControlName="city" [materializeSelectOptions]="cities">
    

    As to why the first select works without that, can't say. Is there an *ngIf="countries" around all that?

    As a side note, you're setting types as initial values. Should be:

    countries: any[]; // = null
    countrySelected: any;
    cities: any[];