Eliya Cohen Eliya Cohen - 1 month ago 13
Javascript Question

Angular 2 update data when another data has been updated

I have two

elements, one for the Districts and the other one for the Cities. I get the districts by calling the function
function. So far so good.

I don't know how to tell angular to fetch the new cities to the cities' select element. I tried to do like in the code below, but I've got an error:

ORIGINAL EXCEPTION: TypeError: Cannot read property 'cities' of undefined

It happens of course because the
is undefined in the start.

This is an example of a district object. (it includes the cities in it).

"id": 5,
"name": "A district",
"cities": [
"id": 59,
"name": "City 1"
"id": 60,
"name": "City 2"


import {Injectable} from "@angular/core";
import 'rxjs/add/operator/toPromise';

import {District} from "./district";
import {HttpClientService} from "../http-client/http-client.service";

export class DistrictService {

private districtsUrl = 'districts/all';

constructor(private httpClient: HttpClientService) {
this.httpClient = httpClient;

getDistricts(): Promise<District[]> {
return this.httpClient.get(this.districtsUrl)
.then(response => response.json().data)

getDistrict(district: string): Promise<District> {
return this.getDistricts()[district];

private handleError(error: any) {
console.error('An error occurred', error);
return Promise.reject(error.message || error);


export class ViewSearchComponent implements OnInit {
districts: district[];
selectedDistrict: district;

constructor(private districtService: districtService) {}

ngOnInit() {

getDistricts() {
return this.districtService.getDistricts().then(districts => this.districts = districts);

selectDistrict(district: district) {
this.selectedDistrict = district;


<select class="search-select">
<option *ngFor="let district of districts" (click)="selectDistrict(district)">
{{ district.name }}

<select class="search-select">
<option *ngFor="let city of selectedDistrict.cities ">
{{ city.name }}


Very few people know that Angular2 supports elvis operator (i.e. ?) in templates which is extremely useful for asynchronous data streams. For that, you have to update the template as,

<select class="search-select">
    <option *ngFor="let city of selectedDistrict?.cities ">
        {{ city.name }}