fetch でデータを取る
このレッスンで分かること
fetchで 1 往復を書くにはawaitが 2 回要ります- 封筒にあたる
responseと、中身のデータは別物です
返事は届いているのに、中身が読めない
fetch はブラウザに用意されている関数で、指定した URL にリクエストを送り、返ってきたレスポンスを Promise で受け取ります。ところが、待って受け取ったはずのものから値を読もうとすると undefined が出ます。
JavaScript
async function peek() {
const response = await fetch("https://yumesaku.tech/course-api/works/2.json");
console.log(response.status); // 200
console.log(response.title); // undefined
}
peek();1 回目の await が終わった時点では、まだ中身は手元にありません。届いているのはステータスコードとヘッダー、つまり封筒の表書きだけです。中身を読むには、もう一度 await が要ります。
| 行 | 待っているもの | 手に入るもの |
|---|---|---|
await fetch(url) | 返事の先頭が届くまで | 封筒にあたる response |
await response.json() | 本文を最後まで読み終わるまで | 配列やオブジェクト |
JavaScript
const response = await fetch("https://yumesaku.tech/course-api/works/2.json");
const work = await response.json();
console.log(work.title); // 自己紹介カード2 回目の await で、本文を最後まで読んで JSON として解釈します。ここで初めて、普通のオブジェクトとして触れるようになります。response.json() も Promise を返すので、await を付け忘れると変数に箱が入り、そこから読む値が全部 undefined になります。
形を確かめてから書く
取ってきたデータの形が分からないまま work.title と書いても、当たるかどうかは運です。書く前に一度 console.log で出してください。{ で始まっていればオブジェクト、[ で始まっていれば配列です。
JavaScript
// works/2.json が返すもの
// {
// "id": 2,
// "title": "自己紹介カード",
// "year": 2026,
// "views": 48,
// "tags": ["HTML", "CSS"]
// }配列になっている項目は、そのまま一覧にできます。入門で書いた描画のやりかたがそのまま使えます。
JavaScript
const list = document.querySelector("#tag-list");
work.tags.forEach(function (tag) {
const item = document.createElement("li");
item.textContent = tag;
list.append(item);
});URL は文字列なので、組み立てられる
fetch に渡すのはただの文字列です。途中に変数を混ぜて組み立てれば、1 件だけ取ってくる形になります。
JavaScript
// スラッシュが 1 本足りない。よくある壊れかた
const url = "https://yumesaku.tech/course-api" + "works/" + id + ".json";
// テンプレートリテラルなら形が見たままになる
const url = `https://yumesaku.tech/course-api/works/${id}.json`;+ でつないでも構いませんが、URL は記号が多いので、${} で埋めるほうが / の付け忘れに気づきやすくなります。存在しない番号を渡すと 404 が返ります。まずは正しい番号で 1 件取れることを確かめてください。
fetchは速いときで数十ミリ秒、遅いときは数秒かかります。そのあいだ画面には何もありません。fetchを呼んだ関数の下に書いた行は、通信が終わる前に走ります。取ってきたデータを使いたい処理は、必ずawaitの下に置いてください。
よくある間違い
fetchにawaitを付け忘れる —responseに箱が入るので、次の行でresponse.json is not a functionと出ます- いちばん外側で
awaitを書く —awaitが使えるのはasyncを付けた関数の中だけです。処理をasync functionにまとめ、呼び出しだけを外に出してください responseをそのまま画面に出す — 封筒を貼り付けているので[object Response]と表示されます。中身を読んでから使います
課題
- async function loadProfile() の中で fetch と response.json() を await する
- #profile-name に name を、#profile-headline に headline を入れる
- #profile-months に months を含む文を入れる
- skills の各要素を li にして #skill-list に足す