43

angular 2 HttpClientを使用してREST経由でデータをフェッチしようとしています。https://angular.io/tutorial/toh-pt6の angular チュートリアルに従っています。Heroes and HTTPセクションの下に、http 経由でヒーロー データを取得するために使用されるこのコード スニペットが表示されます。

getHeroes(): Promise<Hero[]> {
  return this.http.get(this.heroesUrl)
         .toPromise()
         .then(response => response.json().data as Hero[])
         .catch(this.handleError);
}

以下は、アプリケーションで書いた同様のバージョンです

fetch(startIndex: number, limit: number): Promise<Order[]> {
    let url = this.baseUrl + "&startIndex=" + startIndex + "&limit=" + limit;

    return this.http.get(url)
                .toPromise()
                .then(response => response.json().results as Order[])
                .catch(this.handleError);
}

InteliJ Idea を使用していますが、response.json() の呼び出しに赤い線があり、ng buildを使用してビルドしようとしてもエラーが発生します。

プロパティ 'json' はタイプ 'Object' に存在しません。

json().dataあなたは、代わりに私が持っていることに気付くかもしれませんjson().results。これは、チュートリアルによると、サーバーはフィールドを持つdataオブジェクトで応答しましたが、自分のサーバーはフィールドを持つオブジェクトで応答したためresultsです。チュートリアルを少し下にスクロールすると、この点が表示されます。

サーバーが返すデータの形状に注意してください。この特定のメモリ内 Web API の例は、データ プロパティを持つオブジェクトを返します。あなたの API は何か他のものを返すかもしれません。Web API に合わせてコードを調整します。

これを修正するために、私はこのようなことを試しました

(response: Response) => response.json().results as Order[]

私がそれをしたとき、 .json() メソッドは解決されましたが、別のエラーがポップアップしました

Promise 型にプロパティ結果が存在しません

インターフェイスを定義することでそれを修正しようとしました

interface OrderResponse {
    orders: Order[];
}

そして get 呼び出しを変更しました

 .get<OrderResponse>(url)...

しかし、それもうまくいきませんでした。別のエラーが表示されました

タイプ 'OrderResponse' はタイプ 'Response' に割り当てられません。

1 つの注意点として、チュートリアルでは Angular HttpModule を使用していましたが、私のアプリケーションでは新しい Angular HttpClientModule を使用しているため、エラーが発生している可能性があります。

私はAngular 2を初めて使用し、これを使用して構築する最初のアプリです。上記のコードが新しい HttpClientModule で有効でなくなった場合、新しい HttpClientModule で同じことを達成する方法について助けていただければ幸いです。

同様の質問Property 'json' does not exist on type '{}' and Property does not exist on type 'object'を見つけましたが、そこにある回答はどれも役に立ちませんでした。

アップデート

コメントが示唆しているように、新しい HttpClientModule には .json() メソッドはありません。新しいモジュールで同じ効果を達成する方法については、引き続き助けていただければ幸いです。ガイドから、彼らはこのようなことをしました

http.get<ItemsResponse>('/api/items').subscribe(data => {
  // data is now an instance of type ItemsResponse, so you can do this:
  this.results = data.results;
});

私は完全に理解していますが、私の問題は、コードがコンポーネント内ではなくサービス内にあるため、サブスクライブを呼び出して結果をインスタンスフィールドに割り当てることはあまり意味がありません。

Promise でラップされた Orders の配列を返すサービスが必要です。my コンポーネントは次のような呼び出しを行うことができます

this.orderService.fetch(0, 10).then(orders => this.orders = orders)

また、サービスのフェッチ メソッドでローカル変数を宣言して、できるようにすることも考えました。

.subscribe(data => {
    this.orders = data.results;
}
// and out of the get call I return my local variable orders like
return Promise.resolve(orders)

しかし、 .get() への呼び出しは非同期であり、すべてのデータがフェッチされる前にメソッドが返される可能性があり、注文配列が空になる可能性があるため、それは私にはあまり意味がありません。

アップデート

ここで要求されているのは、handleError のコードです。

private handleError(error: any): Promise<any> {
    console.log('An error occured ', error);
    return Promise.reject(error.message || error);
}
4

5 に答える 5