Подтвердить что ты не робот

Angular2: Тип "Подписка" не присваивается типу

Я создал очень небольшое приложение для извлечения стран из json файла и привязки его к выпадающему списку.

countries.json

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

factory.service.ts

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

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

@Injectable()
export class FactoryService {
    private countryUrl = "app/data/countries.json";

    constructor(private http: Http) {

    }

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

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

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

factory -form.component.ts

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';

@Component({
    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[];
    factoryStatuses;
    productTypes;
    risks;
    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 фрагмент

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

Я получаю ошибку времени выполнения, как показано ниже:

Ошибка: Typescript обнаружены следующие ошибки:
C:/Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/factory-form.component.ts(30, 9): Тип "Подписка" не присваивается типу "Страна []".
Длина свойства "длина" отсутствует в типе "Подписка".
C:/Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/shared/country.ts(2, 15): ';' ожидается.     в BroccoliTypeScriptCompiler._doIncrementalBuild (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular -cli\lib\broccoli\broccoli- typescript.js: 120: 19)     в BroccoliTypeScriptCompiler.build(C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular -cli\lib\broccoli\broccoli- typescript.js: 43: 10)     в C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular -cli\node_modules\broccoli-caching-writer\index.js: 152: 21     в lib $rsvp $$ internal $$ tryCatch (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular -cli\node_modules\rsvp\dist\rsvp.js: 1036: 16)     в lib $rsvp $$ internal $$ invokeCallback (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular -cli\node_modules\rsvp\dist\rsvp.js: 1048: 17)     в lib $rsvp $$ internal $$ publish (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular -cli\node_modules\rsvp\dist\rsvp.js: 1019: 11)     в 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)     на process._tickCallback (node.js: 349: 13)

Теперь, если я изменил тип Наблюдаемый и страны на любой, я получаю ниже ошибки

ОРИГИНАЛЬНОЕ ИСКЛЮЧЕНИЕ: Не удается найти отличающийся поддерживающий объект "объект объекта" типа "объект". NgFor поддерживает только привязку к Iterables таких как массивы.

4b9b3361

Ответ 1

Да, тип должен быть Observable, и вам нужно использовать async pipe, чтобы сделать ngFor happy:

*ngFor="let country of countries | async"

Или другой вариант - сохранить тип Country[], но затем подписаться и назначить countries массиву:

this.factoryService.getCountry() // note, removed this.countries = 
    .subscribe(
        countries => this.countries = countries,
        error => this.errorMessage = error
    );