コース一覧
非同期JavaScript:API通信とモジュール
取ったデータを描画する

非同期JavaScript:API通信とモジュール

Promise と async/await、非同期エラー、HTTP/REST、fetch による GET、読み込み・成功・失敗の表示、モジュールの読み方を学ぶ全 19 レッスン(380 分)のコースです。最後は承認済みの読み取り専用 API から作品データを取得して表示します。POST はリクエストの組み立てまでで、外部サービスへの書き込みは行いません。

1
非同期処理
01. 同期と非同期15分
02. Promise をつくって返す20分
03. async と await20分
04. Promise.all で同時に待つ20分
05. 非同期のエラーを捕まえる20分
06. つくる 読み込み中の表示を出す30分
07. 第1章まとめクイズ10分
2
fetch で外のデータを使う
01. HTTP と REST の読みかた15分
02. fetch でデータを取る25分
03. 取ったデータを描画する25分
04. response.ok と失敗時の表示25分
05. POST のリクエストを組み立てる20分
06. つくる 作品データを API から読む30分
07. 第2章まとめクイズ10分
3
モジュールと総仕上げ
01. ファイルを分けるという考えかた15分
02. named export と default export15分
03. つくる ポートフォリオアプリを仕上げる40分
04. ここから先の学びかた15分
05. 第3章まとめクイズ10分

取ったデータを描画する

取ってから画面に出すまで
解説

このレッスンで分かること

  • 取ってきたものが、そのまま配列とは限りません
  • 描き直す前に空にしないと、呼ぶたびに積み上がります

forEach が無いと言われる

取ってきたデータを一覧にしようとして、最初につまずくのがここです。

JavaScript

const data = await response.json(); data.forEach(function (work) { /* ... */ }); // data.forEach is not a function

works.json が返すのは配列そのものではなく、{ count, works } という形のオブジェクトだからです。配列は、そのオブジェクトの中に入っています。

書きかた中身
data{ count: 5, works: [ ... ] } というオブジェクト
data.count5 という数値
data.works作品 5 件が入った配列
data.works[0].title"プロフィールサイト"

入れ物から取り出しさえすれば、そのあとは手で書いた配列とまったく同じです。配列は配列です。だから描画の部分は前のまま使えて、変わるのは「どこから配列を手に入れるか」だけになります。

2 回押すとカードが 2 倍になる

一覧を組み立てる処理は fetch とは別の関数にしておきます。あとで絞り込みや並び替えを足すときに、同じ関数を呼び直すだけで済むからです。ただし、そのときに必ず起きるのがカードの積み上がりです。

JavaScript

function paintTags(tags) { const list = document.querySelector("#tag-list"); list.textContent = ""; // これを書かないと、呼ぶたびに増える tags.forEach(function (tag) { list.append(createTagItem(tag)); }); }

描き直す前に消す、をひとつの型として覚えてください。件数だけが正しくて画面と食い違うときは、たいていこの 1 行が抜けています。

もう 1 つ、配列が空のときも考えます。forEach は空の配列でも静かに何もしません。エラーは出ませんが、画面には何も残らない場所が空いたままになります。利用者から見ると、壊れているのと 0 件だったのとで区別が付きません。

JavaScript

function paintTags(tags) { const list = document.querySelector("#tag-list"); list.textContent = ""; if (tags.length === 0) { list.textContent = "登録されているタグがありません"; return; } tags.forEach(function (tag) { list.append(createTagItem(tag)); }); }

0 件の分岐を先に片づけてしまうと、その下は 1 件以上ある場合だけを考えて書けます。練習用の口には ?empty=1 を用意してあるので、この分岐を実際に通せます。

「読み込み中」は await より前に出す

通信は遅れて届きます。何も出さないでいると、そのあいだの画面は壊れて見えます。ここで大事なのは書く順番です。

JavaScript

async function showTags() { const status = document.querySelector("#status"); status.textContent = "読み込み中"; const response = await fetch("https://yumesaku.tech/course-api/works.json?delay=800"); const data = await response.json(); status.textContent = data.works.length + " 件を読み込みました"; }

先に読み込み中を出してから await します。逆にすると、待ち終わってから読み込み中が出て、すぐ消えることになります。?delay=800 は練習用の口だけが持っている指定で、800 ミリ秒だけ遅れて返してくれます。速い回線でも待っている状態を自分の目で確かめられます。

画面に出す件数は、data.count ではなく実際に描いた配列の length から作ってください。絞り込みを入れると 2 つの数はずれます。数字を手で書くのはもってのほかです。

解説

描画の関数は、配列をもらってカードを並べることしか知りません。通信のことも、絞り込みのことも知らないままにしておくのがこつです。知らないぶんだけ、あとから使い回せます。

よくある間違い

  • 待ちの表示を消し忘れる — 読み込み中が残ったままカードが並んでいる画面は、利用者を不安にさせます。届いたら必ず別の文言に書き換えます
  • data をそのまま回そうとする — 中の配列を取り出してから回します。取ってきたら真っ先に、入れ物の形を見てください

課題

  1. fetch より先に #status へ「読み込み中」を入れる
  2. 1 件につき article.work-card を作り、h3 に title、p.work-meta に年と表示回数を入れる
  3. 描き直す前に .work-list を空にする
  4. #works-count に、描いた件数を入れる

ヒント

読み込み中の代入は await より上に書きます。下に書くと、待ち終わってから出ることになり一瞬しか見えません。

createWorkCard は「作品 1 件をもらってカードを返す」だけにします。append は renderWorks の側でまとめてやると、役割が混ざりません。

件数は data.count でも data.works.length でも同じ数になりますが、あとで絞り込みを足すことを考えて、実際に描いた配列の length から作ってください。

index.html
script.js
プレビュー

できているか

  • fetch を送る前に読み込み中を出す
  • 作品 5 件ぶんのカードが並ぶ
  • 1 枚目のカードに作品名が入る
  • 取ってきた作品をすべて描く
  • 件数をデータから作って出す
エディタを読み込んでいます