Skip to main content
Cascading DropDown list in AngularJS 2

Cascading DropDown List using Angular 2

Previously I posted about how to bind dropdown/select list in angular 2 and in this post, we shall find out how to create cascading dropdown list using Angular 2 by enhancing the same country list Angular 2 application.

Cascading DropDown List using Angular 2

For demo, this angular 2 application will load the list of states in state dropdown based on selected country. Before we continue further, I strongly recommend you to read the post how to bind dropdown/select list in angular 2 to understand code and various new angular 2 concepts used in this application as there is no point repeating the same content here. So as you saw in post, the sample angular 2 application for binding the country list has following structure.

Angular 2 Binding Select application folder structure

And addition to above files, there are a couple of new files added to application and modified some files. We will each of them in detail. First, let’s visit newly added files.

  • state.ts: This file has a simple class called “States” with 3 properties id, countryid and name.
  • dataservice.ts: This is an Angular 2 service which returns a list of countries and states.

Code Walk-through

State.ts

Nothing fancy here. A simple class with 3 properties.

export class State {
  constructor(public id: number, 
              public countryid: int, 
              public name: string) { }
}

DataService.ts

Till Angular 1.x, there are different ways to define a service like factory, service and provider. But with Angular 2, the only way is via classes. Read more about Angular 1.x and Angular 2 difference here. The Angular service can take the data from JSON file, Web API, Web Service or any other local storage. The consumer is not aware of how service is getting the data. So for our service, there is a class defined “DataService” which has 2 methods that returns Countries and States array. Remember, previously we had countries array in Countrylistcomponent.ts file. But as a best practice, it should be part of service as in future if we have to change the way we capture the data there is no need to modify the component or consumer.

Notice, the very first import statement and @Injectable() function as decorator. TypeScript sees the @Injectable() decorator and emits metadata about our service, metadata that Angular may need to inject other dependencies into this service.

Our service doesn’t have any dependencies at the moment. So removing these 2 statements will not break your code but let’s add the decorator anyway. From Angular 2 docs,

It is a “best practice” to apply the @Injectable() decorator ​from the start​ for consistency and for future-proofing.

import { Injectable } from 'angular2/core';
import { Country } from './country';
import { State } from './state';

@Injectable()
export class DataService {
  getCountries() {
    return [
     new Country(1, 'USA' ),
     new Country(2, 'India' ),
     new Country(3, 'Australia' )
    ];
  }
  
  getStates() {
   return [
     new State(1, 1, 'Arizona' ),
     new State(2, 1, 'Alaska' ),
     new State(3, 1, 'Florida'),
     new State(4, 1, 'Hawaii'),
     new State(5, 2, 'Gujarat' ),
     new State(6, 2, 'Goa'),
     new State(7, 2, 'Punjab' ),
     new State(8, 3, 'Queensland' ),
     new State(9, 3, 'South Australia' ),
     new State(10, 3, 'Tasmania')
    ];
  }
}

CountryListComponent.ts

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 and populate countries variable.
  • Also defined onSelect method which will be called onChange event of country dropdown list. This method gets the list of states from our service and then using filter, filter states based on selected country.
import { Component } from 'angular2/core';
import { DataService } from './dataservice';
import { Country } from './country';
import { State } from './state';

@Component({
  selector: 'my-country-list',
  templateUrl: 'app/countrylistcomponent.html',
  providers: [DataService]
})
export class CountryListComponent {
  selectedCountry:Country = new Country(0, 'India'); 
  countries: Country[];
  states: State[];

  constructor(private _dataService: DataService) {
    this.countries = this._dataService.getCountries();
  }
  
  onSelect(countryid) {
    this.states = this._dataService.getStates()
                 .filter((item)=> item.countryid == countryid);
  }
}

CountryListComponent.html

This is the file specified in the templateURL for @Component directive and contains HTML code. 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.

<label>Country:</label> 
<select [(ngModel)]="selectedCountry.id" 
      (change)="onSelect($event.target.value)">
<option value="0">--Select--</option>
<option *ngFor="#country of countries" 
        value= {{country.id}}>{{country.name}}
</option>
</select>
<label>State:</label>
<select>
<option value="0">--Select--</option>
<option *ngFor="#state of states " 
      value= {{state.id}}>{{state.name}}
</option>
</select>

Demo


If you noticed there is functionality that when country is selected, the “–Select–” option from state dropdown is no longer available. So we need to hide the default option whenever any country is selected.

<select>
<option *ngIf='selectedCountry.id == 0' value="0">--Select--</option>
<option *ngFor="#state of states " 
         value= {{state.id}}>{{state.name}}
</option>
</select>

You can download the code from here.

Thank you for reading and I hope it helped you. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.

PS: If you found this content valuable and want to return the favour, then Buy Me A Coffee

11 thoughts to “Cascading DropDown List using Angular 2”

  1. Thanks for sharing but same thing I wanted in Grid structure. But it is not working.

    If you can help.

  2. Thank you for sharing.
    Would you please tell me how to code the “DataService.ts” if I want to take the data from JSON file?
    for example :
    the country.json like this [{“code”:”1″,”name”:”USA”},{“code”:”2″,”name”:”India”},…..]
    and the state.json like this [{“code”:”101″,”countryCode”:”1″,”name”:”Arizona”},{“code”:”201″,”countryCode”:”2″,”name”:”Gujarat”},……]

  3. Thank you for sharing.
    Would you please tell me what the “DataService.ts” be coded, if I take the data from JSON file.

Leave a Reply

Your email address will not be published. Required fields are marked *