こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
<目次>
実装するもの
今回は、Random dad joke APIへリクエストを送り、取得したデータを画面上に表示する処理を実装します。
demoは、「こちら」で確認できます。
環境構築
簡単な環境構築をお願いします。
必要なファイルは、以下の通りです。
1 2 3 4 5 6 |
$ tree . ├── index.html ├── script.js └── style.css |
CSS版
開発
ページの作成
最初にページを作成しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" /> <title>Dad Jokes</title> </head> <body> <div class="container"> <h3>Don't Laugh Challenge</h3> <div id="joke" class="joke">// Joke goes here</div> <button id="jokeBtn" class="btn">Get Another Joke</button> </div> <script src="script.js"></script> </body> </html> |
このHTMLをブラウザ上で表示すると以下のようになります。

スタイルの追加
次にスタイルを記述しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); * { box-sizing: border-box; } body { background-color: #686de0; font-family: 'Roboto', sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; padding: 20px; } .container { background-color: #fff; border-radius: 10px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1); padding: 50px 20px; text-align: center; max-width: 100%; width: 800px; } h3 { margin: 0; opacity: 0.5; letter-spacing: 2px; } .joke { font-size: 30px; letter-spacing: 1px; line-height: 40px; margin: 50px auto; max-width: 600px; } .btn { background-color: #9f68e0; color: #fff; border: 0; border-radius: 10px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1); padding: 14px 40px; font-size: 16px; cursor: pointer; } .btn:active { transform: scale(0.98); } .btn:focus { outline: 0; } |
ここまで実装すると以下のようになります。

JavaScriptの実装
APIの仕様に従って、JavaScriptからHTTPリクエストをAPIに送り、必要なデータを取得します。
例えば、terminal上で
を実行してみると以下のデータが取得できます。curl -H "Accept: application/json" https://icanhazdadjoke.com/
1 2 3 4 5 6 |
$ curl -H "Accept: application/json" https://icanhazdadjoke.com/ { "id": "R7UfaahVfFd", "joke": "My dog used to chase people on a bike a lot. It got so bad I had to take his bike away.", "status": 200 } |
何度か実行すると取得データが変わるので、ランダムで取得しているみたいですね。
要素を取得する
JavaScriptで制御すべき要素が2つあります。最初にこれらの要素を取得しましょう。
1 2 3 |
// 要素を取得 const jokeEl = document.getElementById('joke') const jokeBtn = document.getElementById('jokeBtn') |
fetch APIでリクエスト送信
JavaScriptからAPIへリクエストを送る方法は色々ありますが、今回は「fetch API」を使いましょう。
以下のような感じです。
1 2 3 4 5 6 7 8 |
// ジョークを作成 generateJoke() function generateJoke() { const config = {} // fetchでAPIを叩く fetch('https://icanhazdadjoke.com', config) } |
fetchの第一引数には、APIのURLを指定しました。第二引数には、headerなどのリクエストパラメータを指定します。
リクエストパラメータの作成
fetchへ渡すリクエストパラメータを作成します。
1 2 3 4 5 6 7 8 |
function generateJoke() { const config = { headers: { Accept: 'application/json', }, } // fetchでAPIを叩く } |
APIの戻り値をJSON形式で取得したいので、headersにapplication/jsonを指定しました。これは、
と同義です。$ curl -H "Accept: application/json" https://icanhazdadjoke.com/
リクエスト後のハンドリング
fetchのおかげでAPIへリクエストを飛ばすことができるようになりましたが、APIからのレスポンスを捌く必要があります。
fetchの仕様をみると戻り値にはPromiseオブジェクトが返却されます。このオブジェクトは、
メソッドと Promise.prototype.then()
メソッドを持っています。Promise.prototype.catch()
前者はリクエストが成功したときに実行され、後者は失敗した時に実行されます。
実装してみましょう。
1 2 3 4 5 6 7 8 9 |
function generateJoke() { ... // fetchでAPIを叩く fetch('https://icanhazdadjoke.com', config) // Promise取得 .then((res) => res.json()) // Promseからレスポンスデータ => jsonを抜き取る .then((data) => console.log(data)) // データを出力 .catch((err) => console.log(err)) // エラーの場合こちらに入る。APIのURLを適当なものにすると動作確認できる } |
ブラウザから取得したデータを確認できます。

thenやcatchを使わずに、以下のようにも実装することができます。
1 2 3 4 5 6 7 8 9 10 11 |
function generateJoke() { const config = { headers: { Accept: 'application/json', }, } // fetchでAPIを叩く const res = fetch('https://icanhazdadjoke.com', config) const data = res.json() console.log(data) } |
しかし、この実装の場合はエラーが発生します。

1 2 |
// 発生したエラー script.js:16 Uncaught TypeError: res.json is not a function |
async/await(非同期処理)を実装する
先ほどのエラーは、APIのレスポンスが戻ってくる前にjsonメソッドが実行されたことによって発生しています。
APIへリクエストしてからレスポンスが帰ってくるまでに、多少のタイムラグが発生するからです。
そこで、async/awaitを使ってgenerateJoke関数を非同期処理にします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// 非同期処理であることを示すasyncを関数宣言の前につける async function generateJoke() { const config = { headers: { Accept: 'application/json', }, } // fetchでAPIを叩く // promiseが返却されるまで待つ const res = await fetch('https://icanhazdadjoke.com', config) // resにデータが格納されるまで待つ const data = await res.json() console.log(data) } |
非同期処理にすることで、awaitに指定された処理が完了するまで、JavaScriptを待機させることができます。
これでエラーが消えるはずです。

async/awaitは、then/catchよりもシンプルに書くことができるので、こちらの方がよく使われています。
async/awaitの詳細については、このチュートリアルが参考になると思います。
取得データを表示する
次に取得データをページ上に表示します。
1 2 3 4 5 6 |
// 取得データ { id: "RuHYTSvzsrc", joke: "My wife told me to rub the herbs on the meat for better flavor. That's sage advice.", status: 200 } |
1 2 3 4 5 6 7 |
async function generateJoke() { ... // resにデータが格納されるまで待つ // ページ上に取得データを表示する jokeEl.innerHTML = data.joke } |
jokeElは、ジョークを表示するエリアの要素です。この要素のinnerHTMLプロパティを使えば、データを表示できます。data.jokeのjokeは、取得データのjokeです。
クリックイベントを登録する
最後に、ボタンにクリックイベントを登録しましょう。
1 2 3 4 |
// 要素を取得 ... // クリックイベントを登録 jokeBtn.addEventListener('click', generateJoke) |
これでボタンを押下するごとにAPIへリクエストされるようになります。
これで完了です。
おわりに
APIへリクエストを送り取得したデータを画面上に表示する処理は、現場でもよく実装します。というか大部分のアプリケーションはそうなっているのではないでしょうか。
今回学んだことは他のAPIでも応用が効くと思いますので、習得したい技術ですね^^
それでは、また!
JavaScriptまとめ
JavaScript ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// 要素を取得 const jokeEl = document.getElementById('joke') const jokeBtn = document.getElementById('jokeBtn') // クリックイベントを登録 jokeBtn.addEventListener('click', generateJoke) // ジョークを作成 generateJoke() // 非同期処理であることを示すasyncを関数宣言の前につける async function generateJoke() { const config = { headers: { Accept: 'application/json', }, } // fetchでAPIを叩く // promiseが返却されるまでまつ const res = await fetch('https://icanhazdadjoke.com', config) // resにデータが格納されるまで待つ const data = await res.json() // ページ上に取得データを表示する jokeEl.innerHTML = data.joke } |
コメントを残す
コメントを投稿するにはログインしてください。