Axios 簡単なデモページの作成[JavaScript]

APIから情報を取得する方法を学んだので、
その知識と今まで学んできたことを総合して簡単なデモページを作成していこうと思います。

デモページの内容：

icanhazdadjokeという、APIから英語のjokeを取得するものを使用します。
ボタンをクリックすると、作成したulの中にAPIから取得したjokeをliとして表示する一覧画面を作成していきます。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/9476c480-6aa2-cef6-d4ce-e42821c444b7.png width = 60%>

こちらでは、作成した内容を要約しながら、作成手順や具体的に使用した関数やロジックの内容をまとめていけたらと思います。

目次：
- [HTMLファイル](#htmlファイル)
- [APIの取得　「JavaScriptファイル」 ](#apiの取得javascriptファイル)
- [DOMを操作　「JavaScriptファイル」 ](#domを操作javascriptファイル)

## HTMLファイル

HTMLファイルはシンプルに、h1とbutton、ulだけを用意しています。

また、ulにはidをjokesと付けています。

その他は、app.jsファイルとの接続と、axiosの接続をCDNでしています。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/55654b2e-9450-a628-6407-3ab4b4aab77d.png width= 60%>

```html
<body>
<h1>クリックでジョーク</h1>
<button>クリック</button>
<ul id="jokes"></ul>

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="app.js"></script>
</body>
```

## APIの取得　「JavaScriptファイル」 

AXIOSでヘッダーを指定してリクエストを投げる方法について。

通常のリクエストではHTMLが返ってくるだけだが、このicanhazdadjokeAPIでは、
Acceptというヘッダーで値をapplication/json
とすることで、レスポンスをJSONにすることができました。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/b670dc14-7ad1-e3db-192f-07d123c4bfda.png width = 60%>


これをAXIOSを使った場合、どうすればいいでしょうか？

まずは、APIの中身を取得してみます。
```js
const getDadJoke = async() => {
    const res = await axios.get('https://icanhazdadjoke.com/');
    console.log(res);
}

```

1. getDadJoke関数を作成。非同期処理なので、async、await
2. 関数の中では、axios.getでAPIを呼びます。
3. resの中身を確認してみます。

```js
getDatJoke()
```

レスポンスは返ってきていますが、
headersの中身を確認し、content-typeを見ても、text/htmlになっていることを確認できます。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/97827b6a-3768-e183-4eb1-1887e2904722.png width = 60%>

axiosを使って、getリクエストをしたときに、JSONをもらうためにはどうすればいいでしょうか？

A. APIを取得するURLの第二引数にオブジェクトを渡して取得します。

わかりやすいようにconfigという変数の中で定義をして、ヘッダーを含めたリクエストを投げることができます。

```js
const getDadJoke = async() => {
    const config = {
        headers: {
            Accept:'application/json'
        }
    };
    const res = await axios.get('https://icanhazdadjoke.com/',config);
    console.log(res);
}
```
これで、JSONを取得することができました。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/8ac01503-d068-c4b7-542a-9385846401a3.png width = 60%>

また、下記のコードでAPIのジョークの値を取得することができます。

```js
console.log(res.data.joke);
```
<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/4ed8a632-e6bb-916c-1fac-c62fd805ee00.png width = 60%>

## DOMを操作　「JavaScriptファイル」 

リクエストの投げ方がわかったので、今度はDOMを操作してみたいと思います。

```js
const jokes = document.querySelector('#jokes');

const newLI = document.createElement('LI');
newLI.append(res.data.joke);
jokes.append(newLI);
```

1. ulのid jokesを取得します。
2. liの作成 
3. liの中に、先ほど取得したjokeを挿入します。 
4. newLIをjokes(ul)に追加します。 

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/d3af1e54-ead7-7a55-0e95-412017828f82.png width = 70%>

getDatJoke()を実行するたびに、APIから取得したjokeを画面に出力するとに成功しました。
ページを再読み込みすることなく、外にリクエストを投げて中身を更新することができています。


#### リファクタリング

jokeの取得の関数とjokeの作成の関数を分けてわかりやすいように修正していきます。

```js
const getDadJoke = async() => {
    const config = {
        headers: {
            Accept:'application/json'
        }
    };
    const res = await axios.get('https://icanhazdadjoke.com/',config);
    return res.data.joke
}
```
getDadJoke関数は、res.data.jokeをreturnするように修正します。

```js
const addNewJoke = async() => {
    const jokeText = await getDadJoke();
    const newLI = document.createElement('LI');
    newLI.append(jokeText);
    jokes.append(newLI);
}
```

returnされたres.data.jokeをaddNewJoke関数で使用し、jokeTextに挿入します。
newLIとしてjokeTetxをappendするように修正しました。

#### クリックイベントのハンドラーの作成

```js
const button = document.querySelector('button');

button.addEventListener('click',addNewJoke);

```
1. button要素の取得
2. イベントハンドラーの設定。
2−１. buttonがclickされたときに、 addNewJoke関数が走るように設定します。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/78825b5b-64d9-088b-7da1-88f200b7c6e5.png width = 60%>

ボタンをクリックするたびに、リクエストが飛んで、ulに結果がliとして追加されるようになります。

#### エラーの処理も記載する

try、catchでエラーの時の処理も記載するように修正していきます。

```js
const getDadJoke = async() => {
    try {
        const config = {
            headers: {
                Accept:'application/json'
            }
        };
        const res = await axios.get('https://icanhazdadjoke.coma/',config);
        return res.data.joke
    } catch (e){
        return 'No Jokes Sorry!';
    }
}
```

意図的に取得するAPIのアドレスを適切なものでないものを入力し、エラーを出力させました。

<img src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679750/d90d4274-09ab-91c3-2c61-b1191fa70474.png width = 70%>

意図したエラーが出力されていることが確認できるため、try、catchの挙動が適切なものであることを確認できます。