Reputation: 127
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;
}
}
Upvotes: 0
Views: 1156
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:
public country: Country;
*ngFor="let country of country.data"
Upvotes: 0
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
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
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