Hi, Are you looking to build a dependent or cascading dropdown list dropdown in Angular? Then this blog post is for you. Here you will learn how to build country-state-city dropdowns in Angular step by step. This is called dependent dropdown or cascading dropdown functionality in web development.
This post focuses on creating country, state, and city dropdowns in Angular using PHP APIs. We will also discuss how to populate the dropdowns with data from a database or API and how to populate the select options from API. You check this demo also before starting to code.
Sounds great? Let’s move forward to learn how to build the dependent dropdown in Angular material using API from scratch.
So in this example, we will use PHP to mock the REST APIs in our Angular project. We will call these API endpoints to get the list of the data for countries, states & cities.
Discover how to generate PDFs in PHP dynamically! Learn to generate PDFs from HTML, on button click, and save them to a folder with our comprehensive guide.
Steps for Building Dependent Dropdowns for Location in Angular
If you don’t have Node on your machine then download it from the official website and install it. Once you are done now you need to install Angular. You can install the CLI using the npm package manager:
npm install -g @angular/cli
npm install -g @angular/cli
npm install -g @angular/cli
2. Setup Angular project & UI
Now head over to your working directory in file explorer and open a command prompt or terminal and hit the following command. In this example, the project name is the “dependent_dropdown” we are creating.
ng new dependent_dropdown
ng new dependent_dropdown
ng new dependent_dropdown
This command may take some time to complete depending on the internet connection you have. Once this is completed, move to the working directory by thiscd command and Install Angular Material via the following command.
cd dependent_dropdown
npm install bootstrap
ng add @angular/material
cd dependent_dropdown
npm install bootstrap
ng add @angular/material
cd dependent_dropdown
npm install bootstrap
ng add @angular/material
After installing these packages, go to angular.json file, inside architect > build > styles array add a new item "./node_modules/bootstrap/dist/css/bootstrap.min.css"
Also, if you are using Angular 15 so environment files will not be created, we need to set up those things manually. Create two files environment.ts and environment.prod.ts inside src > app > environments
Here is the screenshot for reference
3. Create Components, Modules & Service files
Since we are using Angular Material, hence we need to import certain modules, so instead we will create a file AngularMaterialModule and import all required modules & finally import this module to AppModule. We need to create a service file also, to write some business logic to call HTTP services.
ng generate module angular-material
ng generate service services/dropdown // This will generate inside services folder
ng generate module angular-material
ng generate service services/dropdown // This will generate inside services folder
ng generate module angular-material
ng generate service services/dropdown // This will generate inside services folder
Update these files as follows.
AngularMaterialModule
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
const materialModules = [
MatInputModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatSelectModule,
MatFormFieldModule,
];
@NgModule({
imports: [CommonModule, ...materialModules],
exports: [...materialModules],
})
export class AngularMaterialModule {}
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
const materialModules = [
MatInputModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatSelectModule,
MatFormFieldModule,
];
@NgModule({
imports: [CommonModule, ...materialModules],
exports: [...materialModules],
})
export class AngularMaterialModule {}
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
const materialModules = [
MatInputModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatSelectModule,
MatFormFieldModule,
];
@NgModule({
imports: [CommonModule, ...materialModules],
exports: [...materialModules],
})
export class AngularMaterialModule {}
Now import this file into the AppModule file as below.
AppModule
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AngularMaterialModule } from './angular-material.module';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
AngularMaterialModule, // <--added
HttpClientModule, // <--added
FormsModule, // <--added
ReactiveFormsModule, // <--added
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AngularMaterialModule } from './angular-material.module';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
AngularMaterialModule, // <--added
HttpClientModule, // <--added
FormsModule, // <--added
ReactiveFormsModule, // <--added
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AngularMaterialModule } from './angular-material.module';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
AngularMaterialModule, // <--added
HttpClientModule, // <--added
FormsModule, // <--added
ReactiveFormsModule, // <--added
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Now let’s add some HTML UI to our component HTML file. Update your app.component.html code.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root',
})
export class DropdownService {
// Update your API path here
private BASE_URL = environment.apiUrl;
constructor(private http: HttpClient) {}
/**
* Fetch All Countries
* @returns Observable
*/
public getCountries(): Observable<any> {
return this.http.get<any>(this.BASE_URL + 'getcountry');
}
/**
* Get states for a country
* @param countryId
* @returns Observable
*/
public getStates(countryId: number): Observable<any> {
return this.http.get<any>(
this.BASE_URL + 'getstate&country_id=' + countryId
);
}
/**
* Get cities for a state
* @param stateId
* @returns Observable
*/
public getCities(stateId: number): Observable<any> {
return this.http.get<any>(this.BASE_URL + 'getcity&state_id=' + stateId);
}
}
environment.ts
export const environment = {
production: false,
apiUrl:
'http://localhost/projects/codingbirds_/country-state-city-dropdown-api/index.php?endpoint=', // you can change your localhost path for api.
};
export const environment = {
production: false,
apiUrl:
'http://localhost/projects/codingbirds_/country-state-city-dropdown-api/index.php?endpoint=', // you can change your localhost path for api.
};
export const environment = {
production: false,
apiUrl:
'http://localhost/projects/codingbirds_/country-state-city-dropdown-api/index.php?endpoint=', // you can change your localhost path for api.
};
Since our frontend work is done, now we need to set up the backend APIs, No No… You don’t need to create APIs, I have already done it for you. Download it from here & setup in locally or on your server.
Or if you do not want to set it up, you can keep the same apiUrl into your environment.ts file as in environment.prod.ts
I already deployed these REST APIs to my server. You can access these APIs by appending these endpoints to the base URL https://demo.codingbirdsonline.com/country-state-city-dropdown-api/
Here are endpoints, params & methods for your reference.
So All the coding part is done, Now it is time to see the actual efforts we made to create Hierarchical location dropdowns in Angular. Save all the files and navigate to http://localhost:4200/ to see the output. You will see something like this.
Source Code & Demo
You can download the full 100% working source code from here. You check this demo also before starting to code. Watch this YouTube video explaining everything about dependent dropdown in Angular using the Country State City dropdown example.
Conclusion
I hope you learned what I explained in the above steps, If you have any suggestions or any errors, or issues please let me know in the comments, definitely I will try to help.
As I have shown If this code works for you, please leave a nice comment so that others can find it useful which always gives me the motivation to create such content.