コレは何?
Angular&TypeScript初心者が、@angular/common/http
を使ってレスポンスをJSONで受け取る部分でのコンパイルエラーに「えっ?型のエラー?どうするの?」と四苦八苦したときの解決メモです。(解決方法が正しくなかったらご指摘いただけると幸いです)
エラーの内容
ERROR in src/app/hoge/hoge.component.ts(xx,yy): error TS2339: Property 'data' does not exist on type 'Object'.
「data
と指定しているけど、そのObject
にはdata
というプロパティ(属性、要素)は存在してないよ。」という内容。意訳すると「(あるかもしれないけど)data
ってプロパティがあるよ、って指定されてないObject
よね」っていう指摘です。
ちなみに、エラー時のhogehoge()
はこうなっています。これを解決する修正方法を以下に2つ書きます。
hogehoge() {
this.http.get('/api/hogehoge').subscribe( res => {
let response = res;
this.test_data = response.data; // <<<<< ココでエラー発生 <<<<<
}, err => {
if(err.status === 401) {
this.router.navigate(['login']);
}
});
}
エラーを修正したコード
シナリオ:「APIエンドポイントの/api/hogehoge
からデータ(JSON)を取得、取得データの要素data
をtest_data
にセットする」
anyを使う
その名の通りでany
は「何でもOK型」です。せっかくのTypeScript
なn....(ry。
実装時は最も速く簡単な指定方法です。
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
.
.
@Component({
.
.
})
export class HogeComponent implements OnInit {
private test_data: String[];
constructor(private http: HttpClient) { }
ngOnInit() { }
hogehoge() {
this.http.get('/api/hogehoge').subscribe( res => {
let response:any = res; // <<<<< 違いはココ <<<<<
this.test_data = response.data;
}, err => {
if(err.status === 401) {
this.router.navigate(['login']);
}
});
}
}
Interfaceを使う
APIからのレスポンスが固定されている場合は恩恵を受けやすい。「あれっ、ここってどんな形でレスポンス返ってくるんだっけ?」というのも起きづらくなるでしょう。
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
.
.
interface ResJSON {
success: boolean; // <<<<< 区切りはコンマ(,)ではなくセミコロン(;) <<<<<
data: any; // <<<<< 区切りはコンマ(,)ではなくセミコロン(;) <<<<<
}
.
.
@Component({
.
.
})
export class HogeComponent implements OnInit {
private test_data: String[];
constructor(private http: HttpClient) { }
ngOnInit() { }
hogehoge() {
this.http.get('/api/hogehoge').subscribe( res => {
let response = <ResJSON>res; // <<<<< 違いはココ <<<<<
this.test_data = response.data;
}, err => {
if(err.status === 401) {
this.router.navigate(['login']);
}
});
}
}
参考
お礼
@takustaqu さん、ありがとうございました!
Interfaceで帰ってくるJSONの通りに型定義しておくか、any型で逃げるかのどちらかで。
— Harada Yayane "Moses" Kiyohide (@takustaqu) July 17, 2018
とはいえちゃんとInterfaceで定義してると後々楽ではあるので。是非。
— Harada Yayane "Moses" Kiyohide (@takustaqu) July 17, 2018