2016-07-09 66 views
10

Ho creato un'applicazione molto piccola per recuperare i paesi da un file JSON e collegarlo al menu a discesa.Angular2: Tipo 'Subscription' non è assegnabile al tipo

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 snippet

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

sto ottenendo errore di runtime, come di seguito:

Error: Typescript found the following errors:
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): Type 'Subscription' is not assignable to type 'Country[]'.
Property 'length' is missing in type 'Subscription'.
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): ';' 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)

Ora Se cambio il tipo di osservabili e paesi a qualsiasi altra parte ottengo sotto l'errore

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

risposta

10

Sì, il tipo deve essere un Observable e è necessario utilizzare il tubo asincrona per rendere ngFor felice:

*ngFor="let country of countries | async" 

o un'altra opzione è quella di mantenere Country[] tipo, ma poi iscriversi e assegnare.210 per array:

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

ottenuto questa eccezione: Invalid argument '[object Object]' per il tubo 'AsyncPipe' –

+0

ho rimosso il tubo asincrono e ho cercato il tuo suggerimento. voilà ha risolto l'errore. perché questo.countries stava dando errore? in pratica stavo solo seguendo il video di Pluralsight e stava lavorando per lei. lei stava usando la beta ma io sto usando rc.4. Ho sprecato 3 ore :( –

+0

fammi sapere il motivo per cui è stato givign error? –

Problemi correlati