Cascading Dropdown Using Angular 7 And Web API

Introduction

 
In this article, I will discuss how to create a cascading dropdown using Angular 7 and Web API. This article has two parts. The first part creates a SQL Server datababase with two tables. The second part creates the Angular app.
 
 
Prerequisite
  • Angular 7 
  • Web API
  • HTML/Bootstrap
  • SQL Server
Cascading DropDownList means a series of dependent DropDownLists where one DropDownList is dependent on another DropDownList. Child DropDownLists are populated based on the item selected in dropdownlist by a user. For example, loading all states in a country.
 
There are three parts of this article.
  1. Create a SQL Server database with two tables, parent and child. 
  2. Create a Web API using ASP.NET Web API Project template
  3. Create an Angular 7  app

Part 1. Create a Database

 
For this article, I have created a database and two tables. If you already have data representing a parent-children form, you may skip this step.
 
Step 1. Open SQL Server Management Studio, connect to a server, and get ready to execute SQL. 
Step 2. Create a database using the following query.
  1. create Database CaseCaddingDDL  

Step 3. Create a table, CountryMaster, using the following query.

  1. CREATE TABLE [dbo].[CountryMaster](    
  2.     [CountryId] [intNOT NULL,    
  3.     [CountryName] [varchar](50) NULL    
  4. )              
 
Step 4. Create a state table, StateMaster, using the following query.
  1. CREATE TABLE [dbo].[StateMaster](      
  2.     [StateID] [int] NOT NULL,      
  3.     [StateName] [varchar](50) NULL,      
  4.     [CountryId] [int] NULL      
  5. )    
 
Step 5. Insert seed ata using the following script.
  1. INSERT [dbo].[CountryMaster] ([CountryId], [CountryName]) VALUES (1, N'INDIA')  
  2. GO  
  3. INSERT [dbo].[CountryMaster] ([CountryId], [CountryName]) VALUES (2, N'AUSTRALIA')  
  4. GO  
  5. INSERT [dbo].[CountryMaster] ([CountryId], [CountryName]) VALUES (3, N'SRILANKA')  
  6. GO  
  7. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (1, N'Rajasthan', 1)  
  8. GO  
  9. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (2, N'Delhi', 1)  
  10. GO  
  11. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (3, N'Gujrat', 1)  
  12. GO  
  13. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (4, N'UttarPradesh', 1)  
  14. GO  
  15. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (5, N'New South Wales', 2)  
  16. GO  
  17. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (6, N'Queensland', 2)  
  18. GO  
  19. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (7, N'South Australia', 2)  
  20. GO  
  21. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (8, N'Tasmania', 2)  
  22. GO  
  23. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (9, N'Western Province', 3)  
  24. GO  
  25. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (10, N'Central Province', 3)  
  26. GO  
  27. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (11, N'Southern Province', 3)  
  28. GO  
  29. INSERT [dbo].[StateMaster] ([StateID], [StateName], [CountryId]) VALUES (12, N'Uva Province', 3)  
  30. GO  
 
 
Now, the database is created and seeded. 

Part 2. Create a Web API

 
For this article, I create a Web API using ASP.NET Web API. 

Step 1

Let's open Visual Studio 2017 or later and create a new Web API project. 
 
Step 2
 
Select File > New > Project.
 
 
Step 3
 
Select Web and ASP.NET Web Application.
 
 
Step 4
 
Then select Web API and then OK.
 
Your project is created and it will look like the following in Solution Explorer.
 
 
Step 5
 
I create a new Controller named Utility using right click on Controllers folder and select Add, and select Controller.
 
Select Web API 2 Controller - Empty. Provide a controller name and click Add. 
 
 
Step 6
 
Now, import our database table's Entity Framework.
 

Step 7

I have enabled Cors using the following steps. 

Add the following reference using NuGet. 

 
 
Add the following line in WebApiConfig to enable Cors.
  1. EnableCorsAttribute cors = new EnableCorsAttribute("*""*""*");  
  2. config.EnableCors(cors);  

WebApiConfig.cs

  1. public static class WebApiConfig  
  2.    {  
  3.        public static void Register(HttpConfiguration config)  
  4.        {  
  5.            // Web API configuration and services  
  6.   
  7.            // Web API routes  
  8.            config.MapHttpAttributeRoutes();  
  9.   
  10.            config.Routes.MapHttpRoute(  
  11.                name: "DefaultApi",  
  12.                routeTemplate: "api/{controller}/{id}",  
  13.                defaults: new { id = RouteParameter.Optional }  
  14.            );  
  15.            EnableCorsAttribute cors = new EnableCorsAttribute("*""*""*");  
  16.            config.EnableCors(cors);  
  17.        }  
  18.    }  

Setp 8 

Add the following method to fetch country data.
  1. [Route("CountryData")]
  2. [HttpGet]
  3. public List<CountryMaster> CountryData()
  4. {
  5.      return ccddlEN.CountryMasters.ToList<CountryMaster>();
  6. }
Setp 9 
 
Add another method to fetch state data. 
  1. [Route("StateData")]  
  2. [HttpGet]  
  3. public List<StateMaster> StateData(int CountryId)  
  4. {  
  5.     return ccddlEN.StateMasters.Where(s => s.CountryId == CountryId).ToList<StateMaster>();  
  6. }  

Complete code for the Utility controller. 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Net;  
  5. using System.Net.Http;  
  6. using System.Web.Http;  
  7. using CaseCaddingDDL.Models;  
  8.   
  9. namespace CaseCaddingDDL.Controllers  
  10. {  
  11.     [RoutePrefix("Api/Utility")]  
  12.     public class UtilityController : ApiController  
  13.     {  
  14.         CaseCaddingDDLEntities ccddlEN = new CaseCaddingDDLEntities();  
  15.         [Route("CountryData")]  
  16.         [HttpGet]  
  17.         public List<CountryMaster> CountryData()  
  18.         {  
  19.             return ccddlEN.CountryMasters.ToList<CountryMaster>();  
  20.         }  
  21.         [Route("StateData")]  
  22.         [HttpGet]  
  23.         public List<StateMaster> StateData(int CountryId)  
  24.         {  
  25.             return ccddlEN.StateMasters.Where(s => s.CountryId == CountryId).ToList<StateMaster>();  
  26.         }  
  27.     }  
  28. }  
  29.    

Part 3. Create an Angular 7 App

 
For this part, I will create a Angular 7 app and call API to get the data.

Step 1 
 
Create an Angular project using the following command in command prompt.
  1. ng new casecaddingDDL  

Step 2 

Open Project in Visual Studio Code using the following command in command prompt.
  1. cd casecaddingDDL  
  1. open .  

Now open project in Visual Studio Code. The project looks like the following:

 
Step 3
 
Create a student service in a student folder using the following command.
  1. ng g service student   

Step 4

Create a method and call the country data API.
  1. CountryDDL(): Observable<CountryVM[]>    
  2.   {    
  3.     return this.http.get<CountryVM[]>(this.Url + '/CountryData');    
  4.   }   

Step 5 

Create a method and call a the state data API.
  1. StateDDL(CountryId: string): Observable<StateVM[]>    
  2.   {    
  3.     return this.http.get<StateVM[]>(this.Url + '/StateData?CountryId='+CountryId);    
  4.   }  

Complete code for student.service.ts.

  1. import { Injectable } from '@angular/core';  
  2. import {HttpClient} from '@angular/common/http';  
  3. import { Observable } from 'rxjs';  
  4. import { CountryVM } from '../Classes/country-vm';  
  5. import { StateVM } from '../Classes/state-vm';  
  6.   
  7. @Injectable({  
  8.   providedIn: 'root'  
  9. })  
  10. export class StudentService {  
  11.   Url = 'http://localhost:50613/Api/Utility';  
  12.   constructor(private http:HttpClient) { }  
  13.   CountryDDL(): Observable<CountryVM[]>  
  14.   {  
  15.     return this.http.get<CountryVM[]>(this.Url + '/CountryData');  
  16.   }  
  17.   StateDDL(CountryId: string): Observable<StateVM[]>  
  18.   {  
  19.     return this.http.get<StateVM[]>(this.Url + '/StateData?CountryId='+CountryId);  
  20.   }  
  21. }  

Step 6 

Create a student component in the student folder using the following commad. 
  1. ng g c student  
student.component.ts 
  1. import { Component, OnInit } from '@angular/core';  
  2. import { NgForm, FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';  
  3. import { Observable } from 'rxjs';  
  4. import { StateVM } from 'src/app/Classes/state-vm';  
  5. import { CountryVM } from 'src/app/Classes/country-vm';  
  6. import { StudentService } from 'src/app/Services/student.service';  
  7. import { HttpClient, HttpHeaders } from "@angular/common/http";  
  8. @Component({  
  9.   selector: 'app-student',  
  10.   templateUrl: './student.component.html',  
  11.   styleUrls: ['./student.component.css']  
  12. })  
  13. export class StudentComponent implements OnInit {  
  14.   private _allCountry: Observable<CountryVM[]>;  
  15.   private _allState: Observable<StateVM[]>;  
  16.   SelCountryId:string="0";  
  17.   FromStudent: any;  
  18.   constructor(private formbulider: FormBuilder,private StudentService:StudentService) { }  
  19.   FillCountryDDL()  
  20.   {  
  21.     debugger;  
  22.     this._allCountry=this.StudentService.CountryDDL();  
  23.   }  
  24.   FillStateDDL()  
  25.   {  
  26.     debugger;  
  27.     this._allState=this.StudentService.StateDDL(this.SelCountryId);  
  28.   }  
  29.   ngOnInit() {  
  30.     this.FromStudent = this.formbulider.group({  
  31.       StudentName: ['', [Validators.required]],  
  32.       Country: ['', [Validators.required]],  
  33.       State: ['', [Validators.required]]  
  34.     });  
  35.     this.FillCountryDDL();  
  36.   }  
  37.   
  38. }         

Front End Design

I have used 2 DropDownLists, one for each entity, country and state.

  1. Country - List of countries.
  2. State - List of states.

I have added a ChangeEvent to Country and also set ngmodel set property to SelCountryId.

  1. <select  class="form-control"  formControlName="Country"  [(ngModel)]="SelCountryId" (change)="FillStateDDL();">      
Student.Component.html
  1. <div class="card">  
  2.   <div class="card-header" style="text-align:center"><b>WEL COME TO CASECADDING DROP DOWN EXAMPLE</b></div>  
  3.   <div class="card-body">  
  4.     <form  [formGroup]="FromStudent" >  
  5.         <div class="row">  
  6.             <div class="form-group col-sm-3">   
  7.                 <label for="company">Student Name</label>  
  8.                 <input type="text" class="form-                               control"  formControlName="StudentName"   id="company" placeholder="Enter Student Name" >  
  9.             </div>  
  10.             <div class="form-group col-sm-3">   
  11.                 <label for="company">Country</label>  
  12.                 <select  class="form-control"  formControlName="Country"  [(ngModel)]="SelCountryId" (change)="FillStateDDL();">  
  13.                   <option value="">--Select--</option>  
  14.                   <option *ngFor="let Country of _allCountry | async" value={{Country.CountryId}}>  
  15.                       {{Country.CountryName}}  
  16.                   </option>  
  17.             </select>  
  18.             </div>  
  19.             <div class="form-group col-sm-3">   
  20.   
  21.                 <label for="company">State Name</label>  
  22.                 <select  class="form-control"  formControlName="State">  
  23.                   <option value="">--Select--</option>  
  24.                   <option *ngFor="let State of _allState | async" value={{State.StateId}}>  
  25.                       {{State.StateName}}  
  26.                   </option>  
  27.             </select>  
  28.             </div>  
  29.         </div>  
  30.     </form>  
  31.   </div>   

Step 7

Let's run the project using the following command in terminal and check the results.
  1. npm start   
 

 

Summary

 
In this article, I have discussed how to create cascading DropDown lists using Angular 7 and Web API.  In my next article, I am going to discuss Editable Table using Angular 7.