Kamran Pervaiz Kamran Pervaiz - 1 year ago 766
Javascript Question

Angular2 : Type 'Subscription' is not assignable to type

I have created a very small application to fetch countries from a json file and bind it to dropdown.


export class Country {
id: number;
name: string;


import { Injectable } from '@angular/core';
import { Http, Response} from '@angular/http';
import { Observable } from 'rxjs/Observable';

import { Country } from './shared/country';

export class FactoryService {
private countryUrl = "app/data/countries.json";

constructor(private http: Http) {


getCountry(): Observable<any> {
return this.http.get(this.countryUrl)
.do(data => console.log("get Countries from json: " + JSON.stringify(data)))

private extractData(response: Response) {
let body = response.json();
return body || {};

private handleError(error: Response) {
return Observable.throw(error.json().error || "500 internal server error");


import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

import { Factory } from './factory';
import { Country } from './shared/country';
import { FactoryService } from './factory.service';

moduleId: module.id,
selector: 'factory-form',
templateUrl: './factory-form.component.html',
styleUrls: ['./factory-form.component.css'],
providers: [FactoryService]
export class FactoryFormComponent implements OnInit{

private model: Factory;
countries: Country[];
private errorMessage: string;
private submitted = false;

constructor(private factoryService: FactoryService) {


ngOnInit(): void {
this.countries = this.factoryService.getCountry()
.subscribe(countries => this.countries = countries,
error => this.errorMessage = error);

onSubmit(): void {
this.submitted = true;

factory-form.component.html snippet

<div class="col-lg-3">
<select class="form-control" name="Country">
<option *ngFor="let country of countries" [value]="country.id">{{country.name}}</option>

I am getting runtime error as below:

Error: Typescript found the following errors:

(30, 9): Type 'Subscription' is not assignable to type 'Country[]'.

Property 'length' is missing in type 'Subscription'.

(2, 15): ';' expected.
at BroccoliTypeScriptCompiler._doIncrementalBuild (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:120:19)
at BroccoliTypeScriptCompiler.build (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:43:10)
at C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\broccoli-caching-writer\index.js:152:21
at lib$rsvp$$internal$$tryCatch (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1048:17)
at lib$rsvp$$internal$$publish (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1019:11)
at lib$rsvp$asap$$flush (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1198:9)
at nextTickCallbackWith0Args (node.js:420:9)
at process._tickCallback (node.js:349:13)

Now If I change the Type of Observable and countries to any then i get below error

ORIGINAL EXCEPTION: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables
such as Arrays.

Answer Source

Yes, the type must be an Observable and the you need to use async pipe to make ngFor happy:

*ngFor="let country of countries | async"

Or another option is to keep Country[] type but then subscribe and assign countries to array:

this.factoryService.getCountry() // note, removed this.countries = 
        countries => this.countries = countries,
        error => this.errorMessage = error
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download