- Create an angular project with the below command.
ng new angular-load-data-based-on-selection
2. After successful creation of the angular app, change the file directory to project-name. “cd angular-load-data-based-on-selection”
Open the project in vs code using “code .” in terminal or open with vs code. Then run the project using “ng serve” in a terminal. Open project in chrome using
localhost:4200
3. Open the app component in vs code and remove the content which is created by angular CLI while creating the app.
For Adding angular material using the command
"ng add @angular/material"
4. Select theme, Am selecting Indigo/Pink,
and click below items as “yes”
- Set up global Angular Material typography styles? Am selecting
y
- Set up browser animations for Angular Material? (Y/n) Select ‘y’.
5. Created Shared Module in the libs folder using “ng generate module shared”. And import, and export material modules in “shared.module.ts”. And also add in the app.module.ts
6. Add “ReactiveFormsModule”, and “Forms Module” in app.module.ts as below.
import { FormsModule, ReactiveFormsModule } from '@angular/forms';@NgModule({
declarations: [
AppComponent,
SignupComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
SharedModule
],
providers: [],
bootstrap: [AppComponent]
})export class AppModule { }
7. Open “app.component.ts”, then add “formbuilder ” as a dependency in the constructor. Create a form variable above the constructor.
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';public form:FormGroup;constructor(private fb:FormBuilder) { }ngOnInit(): void { }
8. Create the formInit() method to initialize the form and call the formInit() method from either constructor() or ngOnInit().
constructor(private fb:FormBuilder) {
this.formInit()
}ngOnInit(): void { }
private formInit(){}
9. And create a form group using form builder and add form controls in the form. and also create three methods to perform selection change.
- Create three variables to store the country’s data, state data, and cities data.
- The getAllCountries() method is for loading all the countries. It will be called when the component is rendered.
- The getStateByCountryId() method is for loading the states based on the country-id. It will be called when the country is selected from Html.
- The getCitiesByStateName() method is for loading the cities based on the state-name. It will be called when the state is selected from Html.
public form:FormGroup;
public countries=[];
public cities=[];
public states=[];private formInit(){
this.form = this.fb.group({
country: ['',[Validators.required]],
state: ['',[Validators.required]],
city: ['',[Validators.required]]
});
}public getAllCountries(){}public getStateByCountryId(){}public getCitiesByStateName(){}.
10. After successfully following the above points and adding the below html to render the countries, states, and cities dropdown. Also, add the respective methods while changing the dropdowns inside the selection change event.
- Disabling the states and cites by default based on country selection states will be loaded and state dropdown will be enabled.
- Disabling the states and cites by default based on country selection and state selection then only city dropdown will be enabled.
<div class="container">
<form class="form shadow m-3 p-3" [formGroup]="form">
<h1 class="mt-3">Load dropdowns based on selection</h1>
<div class="row">
<h4 class="col-md-4">Country</h4>
<mat-form-field style="width:90%" appearance="outline" [floatLabel]="'never'">
<mat-select formControlName="country" (selectionChange)="getStateByCountryId()"
placeholder="Select Country">
<mat-option *ngFor="let country of countries" [value]="country">{{country?.country}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="row">
<h4 class="col-md-4">State</h4>
<mat-form-field style="width:90%" appearance="outline" [floatLabel]="'never'">
<mat-select formControlName="state" (selectionChange)="getCitiesByStateName()"
[disabled]="!form.controls.country.valid" placeholder="Select State">
<mat-option *ngFor="let state of states" [value]="state">{{state?.state}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="row">
<h4 class="col-md-4">City</h4>
<mat-form-field style="width:90%" appearance="outline" [floatLabel]="'never'">
<mat-select formControlName="city" [disabled]="!form.controls.state.valid" placeholder="Select City">
<ng-container *ngFor="let city of cities">
<mat-option [value]="city">{{city?.name}}</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</div>
</form>
</div>
11. After successfully adding the HTML code and checking the changes in the browser by using localhost:4200.If anything wrong and not working please check all the above points.
12. Opps !!!, Not created the service files to call the service, Create three service files under apis folder to load countries, states, and cites. States and cities will be loaded based on selection.
ng generate service countries
ng generate service states
ng generate service cities
13. After successfully creating the files. Add HttpClientModule inside the app.module.ts.
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
SharedModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
14. After that open the countries.service.ts file and import HttpClient and add it as a dependency inside the Constructor. Create the getAllCountries() method to call the service to get all the countries.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';@Injectable({
providedIn: 'root'
})
export class CountryService {
public URL=environment.letsTalkURI || "http://localhost:3000"constructor(private http:HttpClient) { }public getAllCountries(){
return this.http.get(`${this.URL}/public/countries`);
}
}
15. Open the states.service.ts file and import HttpClient and add it as a dependency inside the constructor. Create the getStateByCountryId() method to call the service to get all the states based on country-id.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';@Injectable({
providedIn: 'root'
})
export class StateService {
public URL=environment.letsTalkURI || "http://localhost:3000"constructor(private http:HttpClient) { }public getStateByCountryId(countryId:string | number){
return this.http.get(`${this.URL}/public/states/${countryId}`);
}
}
16. Open the cities.service.ts file and import HttpClient and add it as a dependency inside the constructor. Create the getCityByStateName() method to call the service to get all the cities based on state-name.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';@Injectable({
providedIn: 'root'
})
export class CityService {
public URL=environment.letsTalkURI || "http://localhost:3000"constructor(private http:HttpClient) { }public getCityByStateName(stateName:string){
return this.http.get(`${this.URL}/public/cities/${stateName}`);
}
}
17. After completing the all above steps. Open the app.component.ts and add import three services, add it as a dependency in the constructor like below
import { CityService } from './apis/city.service';
import { CountryService } from './apis/country.service';
import { StateService } from './apis/state.service';constructor(private fb:FormBuilder,
private countryService:CountryService,
private stateService:StateService,
private cityService:CityService
) {
this.formInit();
}
18. After that load countries from country service in side app.component.ts. Call the method from either constructor or ngOnInit() and store the api response in the countries variable.
public ngOnInit():void {
this.getAllCountries();
}public getAllCountries(){
this.countryService.getAllCountries().subscribe((res:any)=>{
this.countries = res.countries && res.countries.length > 0 ? res.countries : []
},error=>{
console.log(error)
})
}
19. Open app.component.ts and call the state service inside the getStateByCountryId() method to store the states based on country id.
public getStateByCountryId(){
this.states=[];
this.cities=[];
this.form.get('state').reset();
this.form.get('city').reset();
const country= this.form.get('country').value;
this.stateService.getStateByCountryId(country._id).subscribe((res:any)=>{
this.states = res.states && res.states.length > 0 ? res.states : []
},error=>{
console.log(error)
})
}
20. Open app.component.ts and call the cities service inside the getCitiesByStateName() method to load the cities based on the state name.
public getCitiesByStateName(){
this.cities=[];
this.form.get('city').reset();
const state= this.form.get('state').value;
this.cityService.getCityByStateName(state.state).subscribe((res:any)=>{
this.cities = res.cities && res.cities.length > 0 ? res.cities : []
},error=>{
console.log(error)
})
}
21. Check the app.component.ts, if everything is aligned properly. If not aligned properly please check all the above steps.
22. After all the above steps are completed, run npm install and ng serve and open the application by using localhost:4200
Output:
Screen #1:
Screen #2: If you click on the countries dropdown, you can able to see all the countries inside the dropdown.
Screen #3: Based on the country selection the states dropdown will be loaded.
Screen #4: Based on state selection the city dropdown will be loaded.
Screen #5: If State is touched and not selected the input border will be red.
Screen #6: If City is touched and not selected the input border will be red.
Source CodeFront End:
GitHub:
https://github.com/mryenagandula/angular-load-data-based-on-selectionBack End:
GITHUB: https://github.com/mryenagandula/Letstalk-BackendLive Backend URI: https://letstalk-be.herokuapp.com/Stack Blitz Project Live Preview:
https://stackblitz.com/edit/angular-material-forms-and-form-array
Thanks for reading my article, Please share your feedback, claps, and comments. In that way, it will be helped me to improve my articles in the future. Please share my story with your near and dear, Also follow and subscribe to the medium.