2016-05-14 31 views
16

Sto imparando Angular2 e Typescript. Sto lavorando al tutorial di Heroes su angular.io, ma applicandolo a un progetto che sto convertendo da ASP.Net. Mi sono imbattuto in un problema che penso sia dovuto alla mia mancanza di comprensione, anche se per quanto posso vedere corrisponde a ciò che la parte rilevante del tutorial sta facendo.Osservabile <{}> non assegnabile al tipo Osservabile <SomeType[]>

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

@Injectable() 
export class RiskAssessmentListService { 

    constructor(private http : Http) {} 

    private serviceUrl = "http://myserviceurl/"; 

    getRisks(): Observable<RiskListSummary[]> { 
     return this.http.get(this.serviceUrl) 
      .map(this.extractData()) 
      .catch(this.handleError()); 
    } 

    private extractData(res: Response) { 
     if (res.status < 200 || res.status >= 300) { 
      throw new Error('Bad response status: ' + res.status); 
      } 
     let body = res.json(); 
     return body.data || { }; 
    } 

    private handleError (error: any) { 
     let errMsg = error.message || 'Server error'; 
     console.error(errMsg); // log to console instead 
     return Observable.throw(errMsg); 
    } 
} 

sto ottenendo il seguente errore sulla linea di "ritorno this.http.get (this.serviceUrl)":

Error:(20, 16) TS2322: Type 'Observable<{}>' is not assignable to type 'Observable'. Type '{}' is not assignable to type 'RiskListSummary[]'. Property 'length' is missing in type '{}'.

Se si fa la differenza, sto usando WebStorm (ultima versione), ma penso che questo errore provenga direttamente dal compilatore dattiloscritto. Stavo pensando che forse ho bisogno di un file typings per rxjs, ma il tutorial non ne usa uno, e nessuno di quelli che ho trovato con una "ricerca di digitazioni" ha fatto la differenza

Quanto segue sono le mie dipendenze dal pacchetto. jSON:

"dependencies": { 
    "@angular/common": "2.0.0-rc.1", 
    "@angular/compiler": "2.0.0-rc.1", 
    "@angular/core": "2.0.0-rc.1", 
    "@angular/http": "2.0.0-rc.1", 
    "@angular/platform-browser": "2.0.0-rc.1", 
    "@angular/platform-browser-dynamic": "2.0.0-rc.1", 
    "@angular/router": "2.0.0-rc.1", 
    "@angular/router-deprecated": "2.0.0-rc.1", 
    "@angular/upgrade": "2.0.0-rc.1", 

    "systemjs": "0.19.27", 
    "es6-shim": "^0.35.0", 
    "reflect-metadata": "^0.1.3", 
    "rxjs": "5.0.0-beta.6", 
    "zone.js": "^0.6.12" 

risposta

18

Penso che il problema si trova qui:

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map(this.extractData()) <== passing result of function 
    .catch(this.handleError()); <== passing result of function 
} 

si potrebbe usare solo di passaggio function di riferimento:

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map(this.extractData) 
    .catch(this.handleError); 
} 

ma in questo modo si perderanno this.

Oppure si potrebbe usare bind metodo per mantenere this:

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map(this.extractData.bind(this)) 
    .catch(this.handleError.bind(this)); 
} 

tuttavia si lose type checking.

avrei leva arrow funzioni per poter utilizzare lexical this:

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map((res) => this.extractData(res)) 
    .catch((err) => this.handleError(err)); 
} 

Senza questa this punterà alla funzione in cui è effettuata la chiamata.

+0

Grazie, questo ha fatto il trucco. Avevo pensato che esistessero dei metodi di estensione .Net all'opera nell'esempio originale (https: //angular.io/docs/ts/latest/guide/server-communication.html#). Penso che avrò bisogno di avviare un nuovo progetto seguendo il loro esempio proprio per vedere se questo dà ancora lo stesso errore –

1

Secondo il getRisks() fn, siete tipi da restituire Observable<RiskListSummary[]>. Tuttavia nel codice, stai restituendo body.data || {}. Credo che tu debba interfacciare il tuo RiskListSummary [] ai tuoi dati corporali.

+0

Sì, anche questo funziona (ho cambiato la firma in privato extractData (res: Response): RiskListSummary []). Come nuovo sviluppatore javascript, proveniente da C#, per me ha più senso della funzione lambda. Non sono ancora abbastanza sicuro del langage da dire quale sia la risposta migliore :-( –

1

Ho avuto lo stesso problema, tuttavia non importa quanto ho modificato come sopra menzionato, non funziona ancora. Fino a quando il mio collegio pensano che questa map, catch defination as VSC prompted

modo che il cambiamento corretto dovrebbe essere come (aggiungere tipo scagli la seguente luogo)

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map<RiskListSummary[]>(this.extractData) 
    .catch<RiskListSummary[]>(this.handleError); 
} 

Sono nuovo di dattiloscritto.quindi questo tipo di [firma del metodo] davvero darmi un martello sulla testa :(

Ma alla fine ha funzionato :)

-3

tipografico è uno strumento del compilatore, che darà sempre il tipo di controllo errore di compilazione come qui in In questo caso, il metodo getRisk dovrebbe specificare che restituisce Observable di tipo RiskListSummary, in modo che lo strumento riconosca ciò che è previsto da questo metodo e verificherà la sicurezza del tipo quando utilizzato nel metodo subscribe.

+0

"Typescript is uno strumento per compilatore "? Cosa? –

Problemi correlati