Cascading DropDown List with ASP.NET Core WEB API and Angular 2

Earlier I posted about Cascading DropDown List using Angular 2 and in this post, we take it to next level and implement it with ASP.NET Core Web API and Angular 2. But starting/configuring AngularJS 2 with ASP.NET Core is not straightforward and it requires some manual configurations to be done. If you are not sure how to do it, I recommend you to read this helpful post to find out post how to start with Angular 2 in ASP.NET Core with TypeScript using Visual Studio 2015.

Cascading DropDown List with ASP.NET Core WEB API and Angular 2

I believe now you have an idea about starting with Angular 2. I also followed same steps to configure this demo project as mentioned here. So now let’s move to next part. Please note, I selected the “Web application template” while creating the project but removed all the unnecessary code.

Add Models classes in Models folder

First, add Country and State model classes in Models folder. Following is the code for Country.cs. This class has 2 properties and a method which returns a list of countries. For demo, I used static data but you can also get the same list from database.

GetCountries() method makes call to Country.GetAllCountries(); and returns the list. Where the second method GetState() accepts countryid as parameters and based on the its value, filters the state list and return the same.

Notecountryid parameter is optional for GetState() action method. And also a default value is supplied to it. Why? Well, this actually allows you to pass countryid in querystring. And while calling REST APIs via AngularJS, the arguments/parameters are appended to URL as part of querystring. And that’s why we must allow our API to support querystring. So following URL,http://localhost:53483/api/Home/GetState/1
is similar tohttp://localhost:53483/api/Home/GetState?countryid=1

Angular 2 application structure

Create a folder named “app” in wwwroot folder. If you have already created while configuring Angular 2 then ignore this step. Now within this folder, following files needs to added.

I already explained about this application structure and about code here. But let me just summarize here again.

country.ts: This file has a simple class called Country with 2 properties id and name.

state.ts: This file has a simple class called States with 3 properties id, countryid and name.

countrylistcomponent.ts: This file contains code for defining a component and template used to render HTML. The Component adds the metadata to the class. And it also makes call to Angular 2 Service, which in turn calls WEB API.

As you know Angular 2 is modular. And as here in this service, we need to make use of HTTP service. So we need to import it. Similarly URLSearchParams, which is used to pass arguments to WEB API method. Therefore,import {Http, URLSearchParams} from "angular2/http";

And the other import statement import 'rxjs/Rx';, imports ReactiveX library. The Http service in Angular 1 returns a promise where Angular 2 returns an Observable object. And The Observable classes in Angular 2 are provided by the ReactiveX library.

Here, first we inject $http service in class constructor. And we use http.get() to run our HTTP request. And this returns an Observable object. Since it’s an observable object, we can use map() to convert the response into JSON response.

This file is modified to use the service to get countries and states list.

First, import the Service and then within @Component directive, set providers: [DataService].

And inject the service in CountryListComponent constructor. And in constructor, call getCountries() method to get list of countries from the service. Since the service returns Observable object, we can use .subscribe() method to get the output in variable.

Also defined onSelect method which will be called onChange event of country dropdown list. This method calls service to get the list of states based on selected countryid and then using subscribe get the list in states variable.

This file has code to bootstrap Angular 2 in our application. Along with that, it also bootstrap application root/parent component. Angular’s http module exposes HTTP_PROVIDERS, which has all the providers that we need, to code http action in our service. Therefore add the http providers to the bootstrap, by importing the HTTP_PROVIDERS from angular2/http.

And finally the HTML template. This file name is used while specifying metadata for CountryListComponent class.
There are 2 dropdowns list one for country and other for state and also change event defined on country dropdown list. Angular 2 has different way of defining event. Take the HTML event and wrap it with parentheses. $event.target.value will give the selected country id.

I also want to bring in your attention a change made in Angular 2 version “2.0.0-beta.17” with respect to *ngFor. Previously we were using,

*ngFor="#state of states"

but in this version, it is changed a bit. Instead of “#”, use “let”

*ngFor="let state of states"

And finally since we are using Angular 2 Http service in our application, we need to include the script in the layout. So, open the _Layout.cshtml file located at Views/Shared/ and add the following code right after the script element that loads Angular 2 core.

Wait!!! We still need to show what we have done till now on UI. So open Views/Home/Index.cshtml and add angular component tag <my-country-list></my-country-list> to HTML file. And we also need to load the application and all its modules. So place following script section to the end of the file.

I am doing this in debian, visual studio code and dotnet 1.0.0-rc2-final – but I will spin up my Windows VM tomorrow and give it a try. I have verified CountryTemplate.html pathing is correct (I can’t paste it here, it seems to freak out the reply mechanism)

Hi, I tried to get this to work and it seems close – however the contents of CountryTemplate.html never render. The logging shows that countrylistcomponent.ts is trying to reach out to it, I see a Request code 200 after requesting path ‘/app/CountryTemplate.html’. Any clues? Thank you