【初学】初めてのAPI(fetchとかpromiseとか良くわからない)

fetchなんて一度も使ったことない!

って状態から、なんとか簡単なAPIの加工までできたのでメモしておきます。


やりたいこと

https://holidays-jp.github.io/

このAPIを使って、画面上に簡単に加工したデータを表示したい!


何からすればいいんだ

https://kde.hateblo.jp/entry/2018/10/22/010811

このサイトを参考にさせていただきました。

fetch("https://holidays-jp.github.io/api/v1/date.json")

.then(response =>{
console.log(response);
});

ちゃんとAPIから取得したデータが表示されました!感動!


fetchってなんなのさ

fetchでデータを取ると、返り値としてPromiseを返す。


Promiseってなんなのさ

まだちゃんと詳しく理解していない、、(今度勉強します)

非同期の状態としてreject(失敗)resolved(成功)があって、

成功時は.then以降の処理を実行させ、失敗時は.catch以降の処理を実行できる模様。

つまり上の例のコードは、

https://holidays-jp.github.io/api/v1/date.jsonfetchして、

成功したら(then) ,responseのデータをコンソールに表示してね!というところ。


fetchの成功はどんな成功?

→リクエストを投げてレスポンスを取ることに成功したら。

ここに落とし穴があって、レスポンスが404(サーバーには接続できたけどサイトが見つからなかった)や500(内部サーバーエラー)でもrejectされない!

確かにエラーのレスポンスを取ることには成功しているから、、でもこれじゃ色々困ります。

そこで、response.okを使いました。

200-299 の範囲のステータスであれば、true、そうでなければfalseを返してくれます。

fetch("https://holidays-jp.github.io/api/v1/date.json")

.then(response =>{
if(response.ok){
return console.log(response);
}else{
return Promise.reject(new Error('エラーです'));
}
})

response.ok = trueだったら、レスポンスデータを表示、

そうじゃなかったら、プロミスをrejectさせます。

これで問題なく取得できますね。でも....

UNADJUSTEDNONRAW_mini_3.jpg

この取得されたデータから、祝日がいつなのかさっぱりですね。


fetchで返ってくるレスポンスって?

【参考】https://qiita.com/uhyo/items/91649e260165b35fecd7

https://qiita.com/koheiyamaguchi0203/items/5777c4653a01ae4c7b06

レスポンスというのは3つの構成に別れていて、

・ステータスコード

・レスポンスヘッダー

・本文(レスポンスボディ)

の順になっています。私が欲しいのはもちろん本文です。

でも、fetchが返されるタイミングはレスポンスヘッダーが全部返ってきたときなのです。

「本文を下さい!」ということで、本文をテキストとして取得します。


本文の取得

fetch("https://holidays-jp.github.io/api/v1/date.json")

.then(response=>{
if(response.ok){
return response.text(); //文字列として取得
}else{
return Promise.reject(new Error('エラーです'));
}
})
.then(response =>{
console.log(response);
})

結果:

2019-07-12 12.20のイメージ.jpg

おお!休日がズラッと取得できました!(text()以外にも取得の形式指定は色々あるようです。)

オブジェクトっぽいですね。早速ページに書き出してみます。


ページに書き出し(失敗例)

var holiday = document.getElementById('holiday');  //ここに書き出す

.then(response =>{
if(response.ok){
return response.text();
}else{
return Promise.reject(new Error('エラーです'));
}
})
.then(response =>{
Object.keys(response).forEach(function(key){
holiday.innerHTML += response[key] + "は" + key + "<br>"; //書き出し部分
})
})


結果:

2019-07-12 12.27のイメージ.jpg

ナンジャコリャ。どうも形式がオブジェクトじゃないみたい。


jsonをパースする

【参考】https://qiita.com/mitsuhiro_K/items/2d179632f62a591a1582

この返ってくるデータはjson形式というもので(APIの仕様書に書いてあります)、json形式はパース(=オブジェクト形式に変換し直す)を行わないといけないようです。


ページ書き出し(完成)

var holiday = document.getElementById('holiday');

//祝日一覧API
fetch("https://holidays-jp.github.io/api/v1/date.json")
.then(response=>{
if(response.ok){
return response.text();
}else{
return Promise.reject(new Error('エラーです'));
}
})
.then(response =>{
var objRes = JSON.parse(response);
console.log(objRes);
Object.keys(objRes).forEach(function(key){
holiday.innerHTML += objRes[key] + "は" + key + "<br>";
});
})


ちゃんと休みの日が一覧で表示できました!


今後の課題👀

・もっと非同期関連の理屈(promise,fetch等)を理解しないといけない

・ただ表示するだけじゃ味気ない、グラフ化する技術などをを身に付けたい