【Javascript】前編 WebAPIを使って簡単なアプリを実装しよう -作って学ぶWeb制作-

JavaScript実践練習コース

はじめに

こんにちは。ブログを読んでいただきありがとうございます!
さて、初級からシリーズで進めてきた「作って学ぶWeb制作」も上級編のWebAPIを使ったアプリ開発でまとめになります。これまでの復習もかねてアプリを作っていきましょう。前後編の2回で、APIを活用したポケモンの図鑑アプリを開発していきます。

前編ではAPIリクエスト~画面表示まで、後編では画面レイアウト、デザインの実装をしていきます。

PokéAPIについて

今回はPokéAPIを活用していきます。ポケモンに関する豊富なデータを提供してくれる無料のRESTful APIです。APIの使い方や利用可能なエンドポイント一覧、レスポンスのサンプル等は公式サイトから確認できます。

公式サイト
PokéAPI

デモ

ランダムなポケモン24匹をカード形式で一覧表示するWebアプリです。
各カードには日本語名・画像・タイプが表示され、クリックするとカードがくるっとめくれて詳細(HP・身長・体重)を見ることができます。

仕様

以下の仕様をもとに実装を進めていきます。

ランダムに選ばれた24匹のポケモンを表示(PokeAPIを使用)
各カードに名前、画像、タイプを表示
カードをクリックすると裏面に切り替わり、HP・身長・体重を表示
全データを取得完了後に一括で表示し、それまでは「読み込み中…」を表示
カードをクリックしてめくる際はフリップアニメーションを付ける

css、jsファイルは外部ファイルとしてhtmlで読み込みます。

 【実践】APIでポケモン情報を取得して画面に表示しよう

HTMLコード

HTMLコードは以下です。ポケモンを表示する各カードはJavaScriptで動的に生成していきます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ポケモン図鑑 サンプル</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
<h1>ランダムポケモンカード図鑑</h1>
<div id="loading">読み込み中...</div>
<div class="grid" id="card-grid" style="display:none;"></div>

<script type="text/javascript" src="script.js"></script>
</body>
</html>

Javascriptコード

  async function getRandomPokemonIds(count) {
    const maxId = 1025;
    const ids = new Set();
    while (ids.size < count) {
      ids.add(Math.floor(Math.random() * maxId) + 1);
    }
    return Array.from(ids);
  }

  async function fetchPokemonData(id) {
    const mainRes = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
    const mainData = await mainRes.json();
    const speciesRes = await fetch(mainData.species.url);
    const speciesData = await speciesRes.json();


    const jpName = speciesData.names.find(n => n.language.name === 'ja-Hrkt')?.name || mainData.name;
    const jpTypes = mainData.types.map(t => {
      const map = {
        normal: 'ノーマル', fire: 'ほのお', water: 'みず', electric: 'でんき', grass: 'くさ',
        ice: 'こおり', fighting: 'かくとう', poison: 'どく', ground: 'じめん', flying: 'ひこう',
        psychic: 'エスパー', bug: 'むし', rock: 'いわ', ghost: 'ゴースト', dragon: 'ドラゴン',
        dark: 'あく', steel: 'はがね', fairy: 'フェアリー'
      };
      return map[t.type.name] || t.type.name;
    }).join(', ');
    const hpStat = mainData.stats.find(s => s.stat.name === 'hp')?.base_stat || '?';
    return {
      name: jpName,
      img: mainData.sprites.front_default,
      types: jpTypes,
      hp: hpStat,
      height: mainData.height / 10,
      weight: mainData.weight / 10
    };
  }
  async function displayRandomCards() {
    const loading = document.getElementById('loading');
    const container = document.getElementById('card-grid');
    const ids = await getRandomPokemonIds(24);
    const allData = await Promise.all(ids.map(id => fetchPokemonData(id)));

    for (const data of allData) {
      const wrapper = document.createElement('div');
      wrapper.className = 'card-wrapper';
      const card = document.createElement('div');
      card.className = 'card';

      card.innerHTML = `
        <div class="card-face card-front">
          <h3>${data.name}</h3>
          <img src="${data.img}" alt="${data.name}" width="120">
          <div class="type">${data.types}</div>
        </div>
        <div class="card-face card-back">
          <h4>詳細</h4>
          <p>タイプ: ${data.types}</p>
          <p>HP: ${data.hp}</p>
          <p>身長: ${data.height} m</p>
          <p>体重: ${data.weight} kg</p>
        </div>
      `;
      card.addEventListener('click', () => {
        card.classList.toggle('flipped');
      });
      wrapper.appendChild(card);
      container.appendChild(wrapper);
    }
    loading.style.display = 'none';
    container.style.display = 'grid';
  }

  displayRandomCards();

ソースコード ポイント解説

ランダムなポケモンIDを重複なく生成している部分から見てみましょう。

  async function getRandomPokemonIds(count) {
    const maxId = 1025;
    const ids = new Set();
    while (ids.size < count) {
      ids.add(Math.floor(Math.random() * maxId) + 1);
    }
    return Array.from(ids);
  }

Set を使うことで重複なしのID一覧を作成し、Math.floor(Math.random() * maxId) + 1 で1~1025の整数を生成しています。

次にAPIリクエスト部分です。今回はfetch関数を使ってAPIへHTTPリクエストを送信しています。

    const mainRes = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
    const mainData = await mainRes.json();

    const speciesRes = await fetch(mainData.species.url);
    const speciesData = await speciesRes.json();

1回ではポケモンの日本語名など一部の情報が取得できないため2回リクエストします。

fetchの流れ
1.fetch()でURLにアクセス
2.await res.json() でレスポンスをJSオブジェクト化
3.必要な値を抽出して使用

最後にデータを画面に表示する部分を見てみましょう。

    for (const data of allData) {
      const wrapper = document.createElement('div');
      wrapper.className = 'card-wrapper';

      const card = document.createElement('div');
      card.className = 'card';

      card.innerHTML = …省略… ;

      card.addEventListener('click', () => {
        card.classList.toggle('flipped');
      });

      wrapper.appendChild(card);
      container.appendChild(wrapper);
    }

カード要素となるHTMLタグを生成し、innerHTMLで挿入します。addEventListenerでクリック時のアニメーションを設定し、最後にDOMに追加しています。
これをallDataに含まれるデータ分(24体)繰り返すことで、カード一覧が完成します。

ここまでで、画面にポケモンの情報が表示されるところまで実装できました。

まとめ

今回は、ポケモンAPIを使ってランダムなポケモン24体のデータを取得し、取得したデータを元に、ポケモンのカード要素を動的に生成・表示する仕組みを実装しました。後編では、カードのデザインや回転アニメーションについて解説していきます!あわせてみていただけたら嬉しいです。

タイトルとURLをコピーしました