Abid
Abid

Reputation: 127

states and city not populated in dropdown

I am new to Angular and am encountering problems with a dynamic dropdown of country states and cities. Although I have checked whole lot of answers in StackOverflow I am not able to get a clear picture as to how we should successfully code to get the desired results.

countries: {};
states: {};
cities: {};

ngOnInit() {
    this.getCountry()
}

<div class="form-group">
                <select formControlName="country" class="form-control" (change)="onChangeCountry($event.target.value)">
                  <option value="">Select country...</option>
                  <option *ngFor="let country of countries" [value]="country.id">{{country?.name}}</option>
                </select>
            </div>

              <div class="form-group">
                <select formControlName="state" class="form-control" 
           (change)="onChangeState($event.target.value)">
                  <option value="">Select state...</option>
                  <option *ngFor="let state of states" [value]="state.id">{{state?.name}}</option>
                </select>
              </div>
              <div class="form-group">
                <select formControlName="city" class="form-control">
                  <option value="">Select city...</option>
                  <option *ngFor="let city of cities" [value]="city.id">{{city?.name}}</option>
                </select>
              </div>


 getCountry(){
    this._country.getCountries().subscribe((res: any) =>{
        this.countries = res.data;
    });
}
onChangeCountry(countryId: number) {
  if (countryId) {
    this._country.getStates(countryId).subscribe(
      data => {
        console.log(data)
        this.states = data;
        this.cities = null;
      }
    );
  } else {
    this.states = null;
    this.cities = null;
  }
}
onChangeState(stateId: number) {
  if (stateId) {
    this._country.getCities(stateId).subscribe(
      data => 
      this.cities = data
    );
  } else {
    this.cities = null;
  }
}

enter image description here enter image description here enter image description here enter image description here

Upvotes: 0

Views: 1156

Answers (4)

Alin Bizau
Alin Bizau

Reputation: 79

I don't think that you really need to message: 'countries found' because you are not using it. Better idea is to return directly the array of countries for example if you are working on the server side also.

countries: Country[] = [];

private getCountry(): void {
      this._country.getCountries()
          .subscribe(response => this.countries = response.data.data);
}

If you really need that message field, then leave countries like an object, but change the name if is an object not an array and in html template use like this:

in .ts

public country: Country;

in .html

*ngFor="let country of country.data"

Upvotes: 0

Prabhakar Kalaiselvan
Prabhakar Kalaiselvan

Reputation: 68

You are assigning the entire object to states variable instead of the array of states in that object. Change the data being assigned to states in onChangeCountry from:

this.states = data;

to:

this.states = data.data;

Likewise, do similar change for cities assignment in onChangeState.

Upvotes: 0

aks44
aks44

Reputation: 432

In the image you added, you could see that "states found" message is printed in the console.. So the response object is identified correctly. Inside the state object data is the array that hold the list of states.. right? So you need to iterate through states.data instead of states. Apply similar change to cities and countries objects as well..

<option *ngFor="let state of states.data" [value]="state.id">{{state?.name}}</option>

Upvotes: 1

erevos13
erevos13

Reputation: 411

you can try this for the init of the variables,

countries: any[] = [];
states: any[] = [];
cities: any[] = [];

Replace any with what type is each variable.

Upvotes: 1

Related Questions