私はAngular2とTypeScriptを学んでいます。私は、angular.ioのHeroesチュートリアルに取り組んでいますが、ASP.Netから変換しているプロジェクトにそれを適用しています。私が理解できる限り、それがチュートリアルの関連部分がしていることと一致するように見えるけれども、私は私の理解の欠如によると思う問題に遭遇しました。
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);
}
}
「return this.http.get(this.serviceUrl)」という行で次のエラーが表示されます。
エラー:(20、16)TS2322:タイプ 'Observable <{}>'はタイプ 'Observable'に割り当てられません。タイプ「{}」は、タイプ「RiskListSummary []」に割り当てることができません。タイプ '{}'にプロパティ 'length'がありません。
違いがある場合は、webstorm(最新バージョン)を使用していますが、このエラーはTypeScriptコンパイラから直接発生していると思います。 rxjsにはタイピングファイルが必要かもしれないと思っていましたが、チュートリアルでは使用していません。
Package.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"
あなたの問題はここにあると思います:
getRisks(): Observable<RiskListSummary[]> {
return this.http.get(this.serviceUrl)
.map(this.extractData()) <== passing result of function
.catch(this.handleError()); <== passing result of function
}
function
参照を渡すだけで使用できます。
getRisks(): Observable<RiskListSummary[]> {
return this.http.get(this.serviceUrl)
.map(this.extractData)
.catch(this.handleError);
}
しかし、この方法ではthis
を失います。
または、 bind メソッドを使用してthis
を保持できます。
getRisks(): Observable<RiskListSummary[]> {
return this.http.get(this.serviceUrl)
.map(this.extractData.bind(this))
.catch(this.handleError.bind(this));
}
ただし、 型チェックを失います 。
矢印 関数を活用して lexical this を使用できるようにします。
getRisks(): Observable<RiskListSummary[]> {
return this.http.get(this.serviceUrl)
.map(res => this.extractData(res))
.catch(err => this.handleError(err));
}
これがない場合、this
変数は、getRisks()
を含むインスタンスではなく、呼び出しが行われる関数を指します。
私は同じ問題を抱えていましたが、上記のようにどのように変更しても、まだ動作しません。私の大学がこれを見つけるまで マップ、VSCの指示に従って定義をキャッチ
したがって、適切な変更は次のようになります(次の場所に型を追加します)
getRisks(): Observable<RiskListSummary[]> {
return this.http.get(this.serviceUrl)
.map<RiskListSummary[]>(this.extractData)
.catch<RiskListSummary[]>(this.handleError);
}
TypeScriptは初めてです。したがって、この種の[メソッドシグネチャ]は本当に頭にハンマーを与えます:(
しかし、最終的にはうまくいった:)
getRisks()
fnによると、あなたはObservable<RiskListSummary[]>
を返す型です。ただし、コードでは、body.data || {}
を返しています。 RiskListSummary []をbody.dataにインターフェースする必要があると思います。
次を見つけました:AccessTokensがありませんでした。だから、私は変更を加えて機能しました:あなたのモデル(私の場合は国)でファイルを編集してから変更します:
export interface CountryInterface {
"id"?: any;
"name": string;
"order"?: number;
}
export class Country implements CountryInterface {
"id": any;
"name": string;
"order": number;
....
}
に:
export interface CountryInterface {
"id"?: any;
"name": string;
"order"?: number;
accessTokens: any[];
}
export class Country implements CountryInterface {
"id": any;
"name": string;
"order": number;
accessTokens: any[];
...
}