Popular blog tags
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 AngularJS 2 by enhancing the same country list Angularjs 2 application.   Cascading DropDown List using AngularJS 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. And addition to above files, there are 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 list of countries and states. Code Walk-through State.ts Nothing fancy here. A simple class with 3 properties. ? 1 2 3 4 5 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.tsfile. 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. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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, setproviders: [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. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <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. ? 1 2 3 4 5 6 <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.  .