0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

天気予報表示アプリを作りながら学ぶJavaScriptのAPI通信・非同期処理【実践ハンズオン】

0
Last updated at Posted at 2026-08-02

はじめに

「プログラミング上達のためには、まずは何かしらアプリを作ったほうがいい」とは言われるけど、いまいち自分の作りたいものなんてわからないし、どういうアプリを作ればどういう技術が身につくのかもわからない……

そんな方に向けて、本記事では天気予報表示アプリを一緒に作りながら、JavaScriptでのAPI通信や非同期処理の基本を学んでいきます。

完成後は、都市名を入力するだけで現在の天気や週間予報を取得できる、本格的なWebアプリが作れるようになります。

また、ただ完成させるだけではなく、「なぜこのコードを書くのか?」という考え方も解説しながら進めるので、実際の開発にも応用できる知識が身に付きます。

この記事はハンズオン形式で進めるため、ぜひ実際に手を動かしながら一緒に作っていきましょう!


この実装で学べること

  • JavaScriptでのDOM操作・イベント処理
  • fetch()async/awaitを使ったAPI通信とJSONデータの扱い方
  • 関数分割やエラーハンドリングなど、保守しやすいコードを書く考え方

対象読者

向いている人

  • JavaScriptでWebアプリを作ってみたい方
  • APIを利用したアプリ開発に挑戦してみたい方
  • DOM操作や非同期処理を実践を通して学びたい方

向いていない人

  • HTML・CSS・JavaScriptの基本文法をまだ全く学習していない方

必要なもの

  • Visual Studio Code
  • Live Server(VS Code拡張機能)
  • Google ChromeなどのWebブラウザ

全体ロードマップ

Phase0 開発準備

  • Step1 プロジェクトを作成する
  • Step2 アプリ全体の土台を作る

Phase1 UI作成

  • Step1 検索バーを作成する
  • Step2 現在の天気カードを作成する
  • Step3 週間予報カードを作成する

Phase2 ダミーデータ表示

  • Step1 JavaScriptから画面を書き換える
  • Step2 週間予報カードをJavaScriptで動的に生成する

Phase3 APIを理解する

  • Step1 APIからデータを取得してみよう(fetch())
  • Step2 Responseの中身(JSON)を取り出そう
  • Step3 async/awaitを使って非同期処理を書こう

Phase4 現在の天気取得

  • Step1 APIのデータを画面へ表示する
  • Step2 天気コードを「晴れ・くもり・雨」に変換する
  • Step3 天気アイコンをAPIのデータに合わせて切り替える

Phase5 週間予報

  • Step1 週間予報データをAPIから取得しよう
  • Step2 APIのデータから週間予報カードを生成する

Phase6 検索機能

  • Step1 入力された都市名で転機を検索する準備をしよう
  • Step2 都市名から緯度・経度を取得しよう(Geocoding API)
  • Step3 検索した都市の天気を表示しよう

Phase7 UX改善

  • Step1 try...catchを使ってエラーハンドリングを実装しよう
  • Step2 innerHTML +=を改善して、より実務的なコードにしよう

Phase0 開発準備

Step1 JavaScriptから画面を書き換える

今回は、JavaScriptが正しく動作する環境を確認するために、画面上の文字を書き換えてみます。

このステップはとてもシンプルですが、今後の開発で何度も使うDOM操作の基本になります。


このステップの目標

  • JavaScriptが正しく読み込まれていることを確認する
  • JavaScriptからHTMLの内容を書き換えられるようになる

HTMLを準備する

まずは以下のように、JavaScriptから書き換えるための要素を用意します。

index.html

<body>

    <h1 id="title">読み込み中...</h1>

    <script src="script.js"></script>

</body>

変更点

<!-- Phase0 Step1 -->
<h1 id="title">読み込み中...</h1>

JavaScriptから文字を書き換える

続いて、script.jsを作成し、以下のコードを書いてください。

script.js

// HTMLのid="title"を取得
const titleElement = document.getElementById("title");

// テキストを書き換える
titleElement.textContent = "天気予報アプリ";

コード解説

document.getElementById()

const titleElement = document.getElementById("title");

HTMLの中から、指定したidを持つ要素を取得するメソッドです。

今回は

<h1 id="title">

を取得しています。

取得した要素は、titleElementという変数に保存されています。


textContent

titleElement.textContent = "天気予報アプリ";

textContentは、要素の文字を変更するためのプロパティです。

今回実行すると

読み込み中...

天気予報アプリ

へ変更されます。


このステップで覚えること

  • document.getElementById()はHTML要素を取得する
  • textContentは要素の文字を書き換える
  • JavaScriptからHTMLを操作することをDOM操作という

動作確認

ブラウザでindex.htmlを開きましょう。

画面に

天気予報アプリ

と表示されれば成功です。

もし

読み込み中...

のまま変わらない場合は、以下を確認してください。

  • script.jsが正しく読み込まれているか
  • id="title"のスペルが一致しているか
  • script.jsというファイル名になっているか

Phase0 Step1のまとめ

このステップでは、JavaScriptからHTMLを書き換える方法を学びました。

今回使用したgetElementById()textContentは、Webアプリ開発で最もよく使う基本機能の一つです。

次のステップでは、アプリ全体の画面レイアウトを作成していきます。

Step2 アプリ全体の土台を作る

前のステップでは、JavaScriptからHTMLを書き換えられることを確認しました。

今回は、これから実装していく天気予報アプリの土台となる画面を作成します。

この時点では、まだ天気情報は表示されません。

まずはアプリに必要なパーツを用意し、後からJavaScriptでデータを表示できるようにしていきます。


このステップの目標

  • アプリ全体のレイアウトを作成する
  • JavaScriptから操作する要素を用意する
  • 今後の実装がしやすいHTML構造にする

index.htmlを作成する

index.htmlを以下の内容に変更してください。

index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天気予報アプリ</title>

    <link rel="stylesheet" href="style.css">
</head>

<body>

    <div class="container">

        <h1>天気予報</h1>

        <!-- 都市名入力エリア -->
        <div class="search-box">

            <input
                type="text"
                id="city-input"
                placeholder="都市名(例: Tokyo)">

            <button id="search-button">
                検索
            </button>

        </div>

        <!-- 現在の天気 -->
        <section class="current-weather">

            <h2>現在の天気</h2>

            <div id="weather-icon">
                ☀️
            </div>

            <p id="temperature">
                --℃
            </p>

            <p id="humidity">
                湿度:--%
            </p>

            <p id="weather-description">
                ---
            </p>

        </section>

        <!-- 週間予報 -->
        <section class="forecast">

            <h2>週間予報</h2>

            <div id="forecast-list">

            </div>

        </section>

    </div>

    <script src="script.js"></script>

</body>

</html>

変更点

今回は、アプリ全体のレイアウトを追加しました。

特に以下の3つが重要です。

<!-- 都市名入力 -->
<input id="city-input">

<!-- 現在の天気 -->
<section class="current-weather">

<!-- 週間予報 -->
<div id="forecast-list">

これらは後のステップでJavaScriptから操作する要素になります。


コード解説

<section>

<section class="current-weather">

sectionは、関連する内容をひとまとまりにするためのHTMLタグです。

今回は

  • 現在の天気
  • 週間予報

をそれぞれ1つのまとまりとして管理しています。


placeholder

<input
    placeholder="都市名(例: Tokyo)">

入力欄が空のときに表示される説明文です。

実際に入力を始めると、自動的に消えます。


id

<div id="forecast-list">

idは、HTML要素を一意に識別するための名前です。

後ほどJavaScriptで

document.getElementById("forecast-list")

のように取得し、週間予報を表示します。


このステップで覚えること

  • sectionは関連する内容をまとめるためのタグ
  • placeholderは入力欄の説明を表示する
  • idはJavaScriptからHTML要素を操作するために使用する

動作確認

ブラウザを開き、以下のような画面になっていれば成功です。

天気予報

[ 都市名(例: Tokyo) ][検索]

現在の天気

☀️

--℃
湿度:--%
---

週間予報

Phase0 Step2.png

まだ見た目はシンプルですが問題ありません。

次のステップでCSSを追加し、本物の天気アプリのようなデザインへ仕上げていきます。


Phase0 Step2のまとめ

今回は、天気予報アプリの土台となるHTMLを作成しました。

この段階ではまだ動きはありませんが、今後JavaScriptからデータを書き込むための準備が整いました。

次のステップでは、CSSを使って見た目を整え、実際のWebサービスのようなデザインにしていきます。

Phase1 UI作成

Step1 検索バーを作成する

前のフェーズでは、天気予報アプリ全体の土台となるHTMLを作成しました。

今回は、最初にユーザーが操作する検索バーの見た目を整えていきます。

この検索バーは、後のステップで都市名を入力し、天気を検索するために使用します。


このステップの目標

  • 検索バーのレイアウトを整える
  • 入力欄と検索ボタンを横並びにする
  • 本物のWebアプリらしい見た目にする

style.cssを作成する

まずは、style.cssを作成し、以下のコードを書いてください。

style.css

/* ==========================
   全体設定
========================== */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: sans-serif;
    background: linear-gradient(135deg, #74b9ff, #a29bfe);
    min-height: 100vh;

    display: flex;
    justify-content: center;
    align-items: center;

    padding: 30px;
}

/* ==========================
   コンテナ
========================== */

.container {
    width: 100%;
    max-width: 500px;

    background: white;
    border-radius: 16px;

    padding: 30px;

    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}

.container h1 {
    text-align: center;
    margin-bottom: 25px;
}

検索バーのCSSを追加する

続いて、以下のコードを追加してください。

/* ==========================
   Phase1 Step1
   検索バー
========================== */

.search-box {

    display: flex;          /* 横並びにする */

    gap: 10px;              /* 要素同士の間隔 */

    margin-bottom: 30px;    /* 下に余白 */

}

.search-box input {

    flex: 1;                /* 横幅を自動で広げる */

    padding: 12px;

    border: 1px solid #ccc;

    border-radius: 8px;

    font-size: 16px;

}

.search-box button {

    padding: 12px 20px;

    border: none;

    border-radius: 8px;

    background-color: #0984e3;

    color: white;

    cursor: pointer;        /* マウスカーソルを指マークにする */

    transition: 0.3s;       /* ホバー時のアニメーション */

}

.search-box button:hover {

    background-color: #0873c4;

}

コード解説

display: flex

display: flex;

要素を横並びにするためのCSSです。

今回の場合は

入力欄  検索ボタン

のように横並びになります。


gap

gap: 10px;

flexで並べた要素同士の間隔を設定します。

今回は入力欄とボタンの間に10pxの余白を作っています。


flex: 1

flex: 1;

余っている横幅を自動で使う指定です。

これにより、検索ボタンのサイズを保ったまま、入力欄だけが横に広がります。


cursor: pointer

cursor: pointer;

ボタンの上にマウスを乗せると、カーソルが指の形になります。

ユーザーに「クリックできるボタン」であることを伝えるためによく使われます。


transition

transition: 0.3s;

見た目が変化するときに、0.3秒かけてゆっくり変化させます。

今回はホバー時の背景色が滑らかに切り替わります。


このステップで覚えること

  • display: flexで要素を横並びにできる
  • flex: 1で要素の横幅を自動調整できる
  • transitionを使うと自然なアニメーションを付けられる

動作確認

ブラウザを更新してください。

以下のような見た目になっていれば成功です。

          天気予報

┌─────────────────────┐
│ Tokyo              │ [検索]
└─────────────────────┘

Phase1 Step1.png

また、検索ボタンにマウスカーソルを乗せると、

  • ボタンの色が少し濃くなる
  • カーソルが指マークになる

ことも確認してみましょう。


Phase1 Step1のまとめ

今回は検索バーのUIを作成しました。

入力欄と検索ボタンを横並びにし、実際のWebサービスのようなデザインに近づけることができました。

次のステップでは、現在の天気を表示するカードを作成し、アプリ全体の見た目をさらに整えていきます。

Step2 現在の天気カードを作成する

前のステップでは、都市名を入力するための検索バーを作成しました。

今回は、現在の天気を表示するカードのデザインを作成します。

この時点では、まだ実際の天気データは表示しません。

まずは「天気アイコン」「気温」「湿度」「天気」の表示場所を整え、後のステップでJavaScriptからデータを反映できるようにします。


このステップの目標

  • 現在の天気カードのデザインを作成する
  • 天気アイコンや気温を見やすく表示する
  • カードデザインの基本を学ぶ

style.cssを編集する

以下のCSSを追加してください。

style.css

/* ==========================
   Phase1 Step2
   現在の天気
========================== */

.current-weather {

    background: #f8f9fa;

    border-radius: 16px;

    padding: 25px;

    text-align: center;

    margin-bottom: 30px;

}

.current-weather h2 {

    margin-bottom: 20px;

}

#weather-icon {

    font-size: 64px;

    margin-bottom: 15px;

}

#temperature {

    font-size: 40px;

    font-weight: bold;

    margin-bottom: 10px;

}

#humidity,
#weather-description {

    font-size: 18px;

    margin-top: 8px;

}

コード解説

border-radius

border-radius: 16px;

要素の角を丸くするプロパティです。

数値が大きいほど、角がより丸くなります。

今回はカードらしい柔らかいデザインにしています。


text-align

text-align: center;

文字や画像などを中央揃えにします。

今回は、

  • 天気アイコン
  • 気温
  • 湿度
  • 天気

を見やすく中央へ配置しています。


font-size

font-size: 64px;

文字サイズを変更するプロパティです。

今回は天気アイコンを大きく表示し、

font-size: 40px;

では気温を目立たせています。


font-weight

font-weight: bold;

文字を太字にするプロパティです。

気温は一番重要な情報なので、太字にして目立たせています。


このステップで覚えること

  • border-radiusでカードの角を丸くできる
  • text-align: centerで要素を中央揃えにできる
  • font-sizefont-weightを使って重要な情報を強調できる

動作確認

ブラウザを更新してください。

「現在の天気」がカードのような見た目になり、

  • ☀️のアイコンが大きく表示される
  • 気温が大きく太字で表示される
  • 湿度と天気が見やすく配置される

ことを確認してください。

イメージは以下のようになります。

┌──────────────────────────────┐
│        現在の天気            │
│                              │
│            ☀️                │
│                              │
│           25℃               │
│                              │
│         湿度:60%            │
│            晴れ              │
└──────────────────────────────┘

Phase1 Step2.png

まだ表示内容は仮のデータですが、後のステップでAPIから取得したデータへ置き換えていきます。


Phase1 Step2のまとめ

今回は現在の天気カードのUIを作成しました。

カード形式のデザインにすることで、現在の天気が見やすくなりました。

次のステップでは、7日間の天気を一覧表示する週間予報カードを作成し、アプリ全体のレイアウトを完成させます。

Step3 週間予報カードを作成する

前のステップでは、現在の天気を表示するカードを作成しました。

今回は、7日間の天気を一覧で表示する週間予報エリアを作成します。

この時点では、まだ実際の天気データは表示しません。

まずはカードのレイアウトを作成し、後のステップでJavaScriptからAPIのデータを表示できるようにしていきます。


このステップの目標

  • 週間予報エリアを作成する
  • 横に並ぶ予報カードを作成する
  • カードデザインを完成させる

index.htmlを編集する

まずは、週間予報カードがどのように表示されるか分かりやすくするために、仮のカードを追加します。

※後のフェーズでJavaScriptから自動生成するため、この仮データは削除します。

index.html

id="forecast-list"の中を以下のように変更してください。

<div id="forecast-list">

    <!-- Phase1 Step3 仮データ -->

    <div class="forecast-card">
        <p></p>
        <div class="forecast-icon">☀️</div>
        <p>30℃</p>
    </div>

    <div class="forecast-card">
        <p></p>
        <div class="forecast-icon">🌤️</div>
        <p>28℃</p>
    </div>

    <div class="forecast-card">
        <p></p>
        <div class="forecast-icon">☁️</div>
        <p>27℃</p>
    </div>

</div>

style.cssを編集する

続いて、以下のCSSを追加してください。

style.css

/* ==========================
   Phase1 Step3
   週間予報
========================== */

.forecast h2 {

    margin-bottom: 20px;

}

#forecast-list {

    display: flex;

    gap: 12px;

    overflow-x: auto;

}

.forecast-card {

    min-width: 90px;

    background: #f8f9fa;

    border-radius: 12px;

    padding: 15px;

    text-align: center;

    flex-shrink: 0;

}

.forecast-icon {

    font-size: 32px;

    margin: 10px 0;

}

コード解説

overflow-x

overflow-x: auto;

横方向にカードが増えたとき、自動で横スクロールできるようにします。

今回は7日分のカードを並べるため、この設定を追加しています。


min-width

min-width: 90px;

カードの最小幅を指定しています。

画面幅が狭くなっても、カードが小さくなりすぎないようにするためです。


flex-shrink

flex-shrink: 0;

通常、display: flexでは画面幅が足りないと要素が縮みます。

今回はカードのサイズを維持したいので、

flex-shrink: 0;

を指定しています。


overflow-x: autoflex-shrink: 0 の組み合わせ

この2つを組み合わせることで、

  • カードの大きさを保ったまま
  • 横にスクロールできる

ようになります。

レスポンシブ対応でもよく使われる組み合わせです。


このステップで覚えること

  • overflow-x: autoで横スクロールを有効にできる
  • min-widthで要素の最小サイズを指定できる
  • flex-shrink: 0で要素が縮まないようにできる

動作確認

ブラウザを更新してください。

週間予報エリアに、横並びのカードが表示されれば成功です。

イメージは以下のようになります。

週間予報

┌────┐ ┌────┐ ┌────┐
│ 月 │ │ 火 │ │ 水 │
│ ☀️ │ │ 🌤️ │ │ ☁️ │
│30℃│ │28℃│ │27℃│
└────┘ └────┘ └────┘

Phase1 Step3.png

ブラウザの横幅を狭くしても、カードのサイズは維持され、必要に応じて横スクロールできることも確認してみましょう。


Phase1 Step3のまとめ

今回は週間予報カードのUIを作成しました。

これで、天気予報アプリの見た目がほぼ完成しました。

次のフェーズからはいよいよJavaScriptを使い、Open-Meteo APIと連携して、現在の天気や週間予報をリアルタイムで表示できるようにしていきます。

Phase2 ダミーデータ表示

Step1 JavaScriptから画面を書き換える

前のフェーズでは、天気予報アプリの見た目を完成させました。

今回は、JavaScriptを使って現在の天気の表示内容を動的に書き換える処理を実装します。

まだAPIは使用しません。

まずはダミーデータ(仮のデータ)を使って、JavaScriptから画面を更新する方法を学びます。


このステップの目標

  • JavaScriptから現在の天気を表示する
  • HTML要素を取得して内容を書き換える
  • API連携の準備をする

script.jsを編集する

以下のコードを書いてください。

script.js

/* ==========================
   HTML要素を取得
========================== */

// 現在の天気
const weatherIconElement =
    document.getElementById("weather-icon");

const temperatureElement =
    document.getElementById("temperature");

const humidityElement =
    document.getElementById("humidity");

const weatherDescriptionElement =
    document.getElementById("weather-description");


/* ==========================
   ダミーデータ表示
========================== */

// 天気アイコン
weatherIconElement.textContent = "☀️";

// 気温
temperatureElement.textContent = "30℃";

// 湿度
humidityElement.textContent = "湿度:65%";

// 天気
weatherDescriptionElement.textContent = "晴れ";

コード解説

const

const temperatureElement =
    document.getElementById("temperature");

constは、再代入しない値を保存するための変数です。

今回はHTML要素そのものを保存しています。


textContent

temperatureElement.textContent = "30℃";

textContentは、要素の文字列を書き換えるプロパティです。

例えば、

--℃

だった表示が

30℃

へ変更されます。


変数へHTML要素を保存する理由

例えば、

document.getElementById("temperature")

を何度も書くこともできます。

しかし、

const temperatureElement =
    document.getElementById("temperature");

としておけば、

temperatureElement.textContent = "30℃";

と短く書くことができ、コードも読みやすくなります。


このステップで覚えること

  • constを使ってHTML要素を変数へ保存する
  • textContentで文字を書き換えられる
  • HTML要素は一度取得して使い回すとコードが読みやすくなる

動作確認

ブラウザを更新してください。

現在の天気カードが、以下のような表示になれば成功です。

☀️

30℃

湿度:65%

晴れ

週間予報はまだ仮のHTMLのままで問題ありません。


Phase2 Step1のまとめ

今回はJavaScriptを使って、現在の天気カードを書き換える方法を学びました。

このように、JavaScriptからHTMLを書き換えることで、APIから取得したデータも同じ方法で画面へ表示できます。

次のステップでは、JavaScriptを使って週間予報カードを動的に生成し、HTMLを自動で作成する方法を学びます。

Step2 週間予報カードをJavaScriptで動的に生成する

前のステップでは、JavaScriptから現在の天気を書き換えられるようになりました。

今回は、HTMLに直接週間予報カードを書くのではなく、JavaScriptでカードを自動生成するように変更します。

実際の開発では、APIから取得した日数分だけ画面を作ることが多いため、このような書き方がよく使われます。


このステップの目標

  • JavaScriptで週間予報カードを生成する
  • 配列とfor文を使って繰り返し処理を学ぶ
  • innerHTMLを使ってHTMLを追加する

index.htmlを編集する

前のステップで追加した仮の週間予報カードは不要になるため、削除してください。

index.html

<div id="forecast-list">

</div>

変更点

<!-- Phase2 Step2 -->
<div id="forecast-list"></div>

script.jsを編集する

まずは、週間予報を表示する要素を取得します。

/* ==========================
   HTML要素を取得
========================== */

// 週間予報
const forecastListElement =
    document.getElementById("forecast-list");

次に、ダミーデータを追加してください。

/* ==========================
   ダミー週間予報
========================== */

const forecastData = [

    {
        day: "",
        icon: "☀️",
        temperature: "30℃"
    },

    {
        day: "",
        icon: "🌤️",
        temperature: "28℃"
    },

    {
        day: "",
        icon: "☁️",
        temperature: "27℃"
    },

    {
        day: "",
        icon: "🌧️",
        temperature: "25℃"
    },

    {
        day: "",
        icon: "⛈️",
        temperature: "24℃"
    }

];

最後に、カードを生成するコードを追加します。

/* ==========================
   週間予報表示
========================== */

forecastListElement.innerHTML = "";

for (let i = 0; i < forecastData.length; i++) {

    forecastListElement.innerHTML += `

        <div class="forecast-card">

            <p>${forecastData[i].day}</p>

            <div class="forecast-icon">
                ${forecastData[i].icon}
            </div>

            <p>${forecastData[i].temperature}</p>

        </div>

    `;

}

コード解説

配列

const forecastData = [
    ...
];

配列は、複数のデータをまとめて管理するための仕組みです。

今回は、

  • 月曜日
  • 火曜日
  • 水曜日

などの週間予報を1つの配列にまとめています。


for

for (let i = 0; i < forecastData.length; i++)

for文は、同じ処理を繰り返すための構文です。

今回は配列のデータを1件ずつ取り出し、

月

↓

火

↓

水

↓

木

↓

金

の順番でカードを生成しています。


.length

forecastData.length

.lengthは、配列の要素数を取得するプロパティです。

今回の配列には5件入っているため、

forecastData.length

5

になります。


innerHTML

forecastListElement.innerHTML += `
...
`;

innerHTMLはHTMLを文字列として追加・変更できるプロパティです。

今回はテンプレートリテラルを使って、カードのHTMLを1枚ずつ追加しています。

※この書き方は学習用として分かりやすい方法です。後のフェーズで、より実務的な書き方へ改善します。


テンプレートリテラル

${forecastData[i].day}

${}を使うことで、JavaScriptの変数をHTMLの中へ埋め込めます。

例えば、

forecastData[i].day

なら、

<p></p>

というHTMLが生成されます。


このステップで覚えること

  • 配列を使うと複数のデータをまとめて管理できる
  • for文で同じ処理を繰り返せる
  • innerHTMLを使ってJavaScriptからHTMLを生成できる

動作確認

ブラウザを更新してください。

週間予報に、ダミーデータのカードが表示されれば成功です。

週間予報

┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐
│ 月 │ │ 火 │ │ 水 │ │ 木 │ │ 金 │
│ ☀️ │ │ 🌤️ │ │ ☁️ │ │ 🌧️ │ │ ⛈️ │
│30℃│ │28℃│ │27℃│ │25℃│ │24℃│
└────┘ └────┘ └────┘ └────┘ └────┘

現在の天気カードも引き続き表示されていれば問題ありません。


Phase2 Step2のまとめ

今回は、JavaScriptを使って週間予報カードを動的に生成しました。

HTMLに直接カードを書くのではなく、データをもとに画面を作ることで、APIから取得した情報にも柔軟に対応できるようになりました。

次のフェーズでは、いよいよOpen-Meteo APIと連携し、本物の天気データを取得して表示していきます。

Phase3 APIを理解する

Step1 APIからデータを取得してみよう(fetch()

前のフェーズでは、ダミーデータを使って天気情報を表示しました。

しかし、実際の天気予報アプリでは、毎回決まったデータを表示するのではなく、インターネット上のサーバーから最新の天気情報を取得する必要があります。

そこで今回は、JavaScriptのfetch()を使って、Open-Meteo APIへリクエストを送り、実際のデータを取得するところまで実装します。

このステップでは、まだ画面には表示しません。

まずはAPIからデータを取得できることを確認しましょう。


このステップの目標

  • APIとは何かを理解する
  • fetch()を使ってAPIへリクエストを送る
  • ブラウザの開発者ツールで取得結果を確認する

APIとは?

API(Application Programming Interface)とは、他のサービスが持っているデータや機能を利用するための窓口です。

今回はOpen-Meteo APIへ

東京の天気を教えてください

というリクエストを送り、

気温:30℃
湿度:65%
天気:晴れ

のようなデータを受け取ります。

イメージすると、次のような流れになります。

ブラウザ

    │

    ▼

Open-Meteo API

    │

    ▼

天気データを返す

script.jsを編集する

まずは、これまで作成したダミーデータを一旦コメントアウト、または削除してください。

削除するのは以下の部分です。

// ダミーデータ表示

weatherIconElement.textContent = "☀️";

temperatureElement.textContent = "30℃";

humidityElement.textContent = "湿度:65%";

weatherDescriptionElement.textContent = "晴れ";


// ダミー週間予報

const forecastData = [
    ...
];

forecastListElement.innerHTML = "";

for (...) {

    ...

}

続いて、以下のコードを追加してください。

script.js

/* ==========================
   Phase3 Step1
   APIからデータ取得
========================== */

// 東京駅の緯度・経度
const apiUrl =
    "https://api.open-meteo.com/v1/forecast?latitude=35.6812&longitude=139.7671&current=temperature_2m,relative_humidity_2m,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min";

// APIへリクエストを送信
fetch(apiUrl)
    .then(response => {

        // APIから返ってきたデータを確認
        console.log(response);

    });

コード解説

fetch()

fetch(apiUrl)

fetch()は、APIへHTTPリクエストを送信するための関数です。

今回はOpen-Meteo APIへアクセスし、

東京駅周辺の天気情報をください

というリクエストを送っています。


.then()

.then(response => {

});

API通信には少し時間がかかります。

.then()は、

データの取得が終わったあとに実行する処理

を書くためのメソッドです。

今回は取得できたresponseを確認しています。

※後のステップでは、より実務でもよく使われるasync/awaitへ書き換えます。


console.log()

console.log(response);

console.log()は、JavaScriptの値をブラウザのコンソールへ表示するための関数です。

今回はAPIから返ってきたデータを確認するために使用しています。


このステップで覚えること

  • APIは他のサービスからデータを取得するための窓口
  • fetch()でAPIへリクエストを送信できる
  • console.log()を使うと取得したデータを確認できる

動作確認

ブラウザを更新してください。

見た目にはまだ変化はありません。

次に、

ブラウザの開発者ツールを開き、

「Console」タブを確認してください。

以下のようなResponseオブジェクトが表示されていれば成功です。

Response {
    type: "cors",
    url: "...",
    ok: true,
    status: 200,
    ...
}

Phase3 Step1.png

特に、

status: 200

となっていれば、APIとの通信に成功しています。


Phase3 Step1のまとめ

今回は、Open-Meteo APIへリクエストを送り、データを取得するところまで実装しました。

まだ画面には何も表示されませんが、APIとの通信が成功していることを確認できました。

次のステップでは、このResponseオブジェクトの中からJSONデータを取り出し、実際の天気情報を確認していきます。

Step2 Responseの中身(JSON)を取り出そう

前のステップでは、fetch()を使ってOpen-Meteo APIへリクエストを送り、Responseオブジェクトを取得しました。

しかし、このResponseの中には、そのまま天気データが入っているわけではありません。

実際のデータを使うには、Responseの中からJSONデータを取り出す必要があります。

今回は、APIから返ってきたJSONデータを取得し、その中身を確認してみましょう。


このステップの目標

  • response.json()を使ってJSONデータを取得する
  • APIから返ってくるデータ構造を理解する
  • ConsoleでJSONデータを確認する

JSONとは?

JSON(JavaScript Object Notation)は、

データをやり取りするときによく使われる形式です。

例えば今回のAPIでは、

気温:30℃
湿度:65%
天気コード:0

のような情報がJSON形式で送られてきます。

イメージすると、次のような流れになります。

API

↓

Response

↓

response.json()

↓

JavaScriptで扱えるデータ

script.jsを編集する

前回のコードを以下のように変更してください。

script.js

/* ==========================
   Phase3 Step2
   JSONデータ取得
========================== */

// 東京駅の緯度・経度
const apiUrl =
    "https://api.open-meteo.com/v1/forecast?latitude=35.6812&longitude=139.7671&current=temperature_2m,relative_humidity_2m,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min";

// APIへリクエスト
fetch(apiUrl)

    .then(response => {

        // ResponseからJSONデータを取り出す
        return response.json();

    })

    .then(data => {

        // JSONデータを確認
        console.log(data);

    });

コード解説

response.json()

response.json();

response.json()は、

ResponseオブジェクトをJavaScriptで扱えるデータへ変換するメソッドです。

この処理を行うことで、

APIから返ってきたJSONデータを使えるようになります。


return

return response.json();

returnは、処理結果を返すためのキーワードです。

今回は、

response.json()

で取得したデータを次の.then()へ渡しています。


2回目の.then()

.then(data => {

    console.log(data);

});

1回目の.then()ではResponseを受け取りました。

2回目では、

data

として、JSONへ変換されたデータを受け取っています。

つまり、

Response

↓

response.json()

↓

data

という流れになります。


APIから返ってくるデータ

Consoleを開くと、次のようなデータが表示されます。

{
    current: {
        temperature_2m: 30.2,
        relative_humidity_2m: 65,
        weather_code: 0
    },

    daily: {
        time: [...],
        weather_code: [...],
        temperature_2m_max: [...],
        temperature_2m_min: [...]
    }
}

この中で特に使用するのは、

current

daily

です。

  • current:現在の天気
  • daily:週間予報

このステップで覚えること

  • response.json()でJSONデータを取得できる
  • returnで次の.then()へデータを渡せる
  • APIのデータ構造を理解することは実装でとても重要

動作確認

ブラウザを更新し、

開発者ツールのConsoleを開いてください。

次のようなオブジェクトが表示されれば成功です。

{
    current: {...},
    daily: {...}
}

Phase3 Step2.png

currentdailyの横にある▶をクリックすると、

中にどのようなデータが入っているか確認できます。

特に以下の項目を見つけてみましょう。

current
    ├ temperature_2m
    ├ relative_humidity_2m
    └ weather_code

daily
    ├ time
    ├ temperature_2m_max
    ├ temperature_2m_min
    └ weather_code

これらのデータを、後のステップで画面へ表示していきます。


Phase3 Step2のまとめ

今回は、response.json()を使ってResponseオブジェクトからJSONデータを取得しました。

また、APIから返ってくるデータ構造を確認し、現在の天気と週間予報のデータがどこに入っているのかを理解しました。

次のステップでは、asyncawaitを使って、今回の処理をより読みやすく、実務でもよく使われる書き方へリファクタリングしていきます。

Step3 async/awaitを使って非同期処理を書こう

前のステップでは、fetch().then()を使ってAPIからJSONデータを取得しました。

しかし、.then()を何度も繋げていくと、処理の流れが分かりづらくなってしまいます。

そこで今回は、現在のJavaScriptでよく使われている**async/await**を使って、同じ処理をよりシンプルに書き直します。

今後のAPI通信も、この書き方で実装していきます。


このステップの目標

  • async関数を作成する
  • awaitを使って非同期処理を書く
  • .then()との違いを理解する

script.jsを編集する

前のステップで書いたコードを、以下のように変更してください。

script.js

/* ==========================
   Phase3 Step3
   async / await
========================== */

// 東京駅の緯度・経度
const apiUrl =
    "https://api.open-meteo.com/v1/forecast?latitude=35.6812&longitude=139.7671&current=temperature_2m,relative_humidity_2m,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min";

// APIから天気データを取得する関数
async function fetchWeather() {

    // APIへリクエストを送信
    const response = await fetch(apiUrl);

    // JSONデータへ変換
    const data = await response.json();

    // データを確認
    console.log(data);

}

// 関数を実行
fetchWeather();

コード解説

async

async function fetchWeather() {

}

asyncは、非同期処理を行う関数を作るためのキーワードです。

awaitasyncが付いた関数の中でしか使用できません。


await

const response = await fetch(apiUrl);

awaitは、

処理が終わるまで待ってから次の行を実行する

という意味です。

例えば、

const response = await fetch(apiUrl);

では、

  1. APIへリクエストを送る
  2. データが返ってくるまで待つ
  3. responseへ保存する

という流れになります。


await response.json()

const data = await response.json();

こちらも同じように、

JSONへの変換が終わるまで待ってから、

dataへ結果を保存しています。


関数を呼び出す

fetchWeather();

関数を作っただけでは実行されません。

最後に

fetchWeather();

を書くことで、実際にAPI通信が行われます。


.then()との比較

前回は次のように書いていました。

fetch(apiUrl)
    .then(response => response.json())
    .then(data => {
        console.log(data);
    });

今回のasync/awaitでは、

const response = await fetch(apiUrl);

const data = await response.json();

console.log(data);

となります。

処理が上から順番に書かれているため、読みやすくなっています。

実務でも、async/awaitを使う場面が非常に多いです。


このステップで覚えること

  • asyncは非同期処理を行う関数を作るためのキーワード
  • awaitを使うと、処理が終わるまで待ってから次へ進める
  • async/awaitを使うと、.then()よりも読みやすいコードを書ける

動作確認

ブラウザを更新し、

開発者ツールのConsoleを開いてください。

前のステップと同じように、

{
    current: {...},
    daily: {...}
}

というJSONデータが表示されれば成功です。

表示内容は前回と変わりませんが、コードはよりシンプルで読みやすくなっています。


Phase3 Step3のまとめ

今回は、async/awaitを使ってAPI通信を書き直しました。

async/awaitを使うことで、非同期処理でも通常のプログラムのように上から順番に処理を書けるようになり、可読性が大きく向上しました。

次のフェーズでは、取得したJSONデータを解析し、現在の天気や週間予報を実際に画面へ表示していきます。

Phase4 現在の天気取得

Step1 APIのデータを画面へ表示する

前のフェーズでは、Open-Meteo APIからJSONデータを取得できるようになりました。

今回は、そのデータを使って現在の天気を画面へ表示してみましょう。

これまで表示していたダミーデータではなく、APIから取得した気温や湿度をそのまま画面へ反映します。


このステップの目標

  • APIから取得したデータを取り出す
  • 現在の気温・湿度を画面へ表示する
  • オブジェクトから値を取得する方法を学ぶ

APIのデータ構造を確認する

前のステップでConsoleを見ると、次のようなデータが表示されていました。

{
    current: {
        temperature_2m: 30.2,
        relative_humidity_2m: 65,
        weather_code: 0
    },

    daily: {
        ...
    }
}

今回は、このcurrentの中にあるデータを利用します。


script.jsを編集する

fetchWeather()の中を、以下のように変更してください。

script.js

// APIから天気データを取得する関数
async function fetchWeather() {

    // APIへリクエストを送信
    const response = await fetch(apiUrl);

    // JSONデータへ変換
    const data = await response.json();

    // 現在の天気データを取り出す
    const current = data.current;

    // 気温を表示
    temperatureElement.textContent =
        `${current.temperature_2m}℃`;

    // 湿度を表示
    humidityElement.textContent =
        `湿度:${current.relative_humidity_2m}%`;

}

コード解説

data.current

const current = data.current;

currentには、現在の天気に関する情報が入っています。

例えば、

current.temperature_2m

と書くことで、現在の気温を取得できます。


オブジェクトのプロパティ

current.temperature_2m

.(ドット)を使うことで、オブジェクトの中にある値を取り出せます。

今回使用する主なデータは次の2つです。

current.temperature_2m

現在の気温

current.relative_humidity_2m

現在の湿度


テンプレートリテラル

`${current.temperature_2m}℃`

テンプレートリテラルを使うことで、

30.2

という数値と、

という文字を簡単に組み合わせられます。

画面には、

30.2℃

のように表示されます。


このステップで覚えること

  • data.currentから現在の天気データを取得できる
  • .(ドット)を使ってオブジェクトの値を取り出せる
  • テンプレートリテラルで文字列と変数を組み合わせられる

動作確認

ブラウザを更新してください。

現在の天気カードの

  • 気温
  • 湿度

が、実際の天気データへ変わっていれば成功です。

例えば、

☀️

31.2℃

湿度:68%

---

Phase4 Step1.png

のような表示になります。

※天気アイコンと天気の説明は、まだ仮の表示のままで問題ありません。


Phase4 Step1のまとめ

今回は、APIから取得した現在の天気データを画面へ表示しました。

これで、気温と湿度がリアルタイムの情報に更新されるようになりました。

次のステップでは、APIが返すweather_codeを「晴れ」「くもり」「雨」といった分かりやすい天気へ変換して表示していきます。

Step2 天気コードを「晴れ・くもり・雨」に変換する

前のステップでは、APIから取得した気温と湿度を画面へ表示しました。

しかし、現在の天気部分にはまだ

---

と表示されています。

これは、Open-Meteo APIが返している天気情報が、人間に分かりやすい文字ではなく**weather code(天気コード)**という数値で返されているためです。

今回は、この数値を

0 → 晴れ
3 → くもり
61 → 雨

のように変換して表示できるようにします。


このステップの目標

  • weather codeの仕組みを理解する
  • 関数を使ってデータ変換処理を作る
  • 天気コードを画面表示用の文字へ変換する

weather codeとは?

APIから取得できる天気情報は、以下のような数値になっています。

weather code 天気
0 晴れ
1〜3 晴れ〜くもり
45〜48
51〜67
71〜77
80〜82
95〜99 雷雨

このままだとユーザーには分かりづらいため、JavaScriptで変換します。


天気コード変換関数を作成する

script.jsに以下の関数を追加してください。

script.js

/* ==========================
   天気コード変換
========================== */

function getWeatherDescription(weatherCode) {

    // 晴れ
    if (weatherCode === 0) {

        return "晴れ";

    }

    // くもり
    else if (weatherCode <= 3) {

        return "くもり";

    }

    // 雨
    else if (weatherCode >= 51 && weatherCode <= 67) {

        return "";

    }

    // 雪
    else if (weatherCode >= 71 && weatherCode <= 77) {

        return "";

    }

    // 雷雨
    else if (weatherCode >= 95) {

        return "雷雨";

    }

    // その他
    else {

        return "不明";

    }

}

APIデータを画面へ表示する

次に、fetchWeather()内へ天気表示処理を追加します。

script.js

async function fetchWeather() {

    const response = await fetch(apiUrl);

    const data = await response.json();


    // 現在の天気データ
    const current = data.current;


    // 天気コードを取得
    const weatherDescription =
        getWeatherDescription(
            current.weather_code
        );


    // 天気を表示
    weatherDescriptionElement.textContent =
        weatherDescription;

}

コード解説

関数

function getWeatherDescription(weatherCode) {

}

関数は、決まった処理をまとめて再利用する仕組みです。

今回は、

weather code

↓

天気名

へ変換する処理を1つの関数にまとめています。


引数

function getWeatherDescription(weatherCode)

weatherCodeは関数へ渡すデータです。

例えば、

getWeatherDescription(0)

の場合、

晴れ

が返されます。


if

if (weatherCode === 0)

条件によって処理を分岐させる構文です。

今回は、

もし weatherCode が 0なら
    晴れを返す

という処理をしています。


return

return "晴れ";

returnは、関数の結果を返すために使います。

例えば、

const result = getWeatherDescription(0);

の場合、

result

には、

晴れ

が保存されます。


このステップで覚えること

  • APIの数値データは画面表示用に変換する必要がある
  • 関数を使うと処理を整理して再利用できる
  • if文とreturnで条件に応じた値を返せる

動作確認

ブラウザを更新してください。

現在の天気カードの表示が、

☀️

30.5℃

湿度:60%

晴れ

Phase4 Step2.png

のように表示されれば成功です。

天気は場所や時間によって変化するため、

晴れ

以外にも

くもり
雨

などが表示される場合があります。


Phase4 Step2のまとめ

今回は、APIから取得したweather_codeを、人間が理解できる天気表示へ変換しました。

APIでは効率的にデータを扱うために数値で情報を返すことが多く、アプリ側で表示用のデータへ変換する処理は非常によく使われます。

次のステップでは、天気コードに合わせて天気アイコンも自動で切り替わるように実装します。

Step3 天気アイコンをAPIのデータに合わせて切り替える

前のステップでは、weather_codeを利用して、

0 → 晴れ
3 → くもり
61 → 雨

のように、天気コードを人間が分かる文字へ変換しました。

しかし、現在の天気カードではアイコンがまだ固定されています。

今回は、APIから取得した天気コードに応じて、

晴れ → ☀️
くもり → ☁️
雨 → 🌧️

のように、天気アイコンを自動で変更できるようにします。


このステップの目標

  • 天気コードからアイコンを取得する関数を作る
  • APIデータに合わせて表示内容を変更する
  • 複数の変換処理を分けて管理する

天気アイコン変換関数を作成する

script.jsに以下の関数を追加してください。

script.js

/* ==========================
   天気アイコン変換
========================== */

function getWeatherIcon(weatherCode) {

    // 晴れ
    if (weatherCode === 0) {

        return "☀️";

    }

    // くもり
    else if (weatherCode <= 3) {

        return "☁️";

    }

    // 雨
    else if (weatherCode >= 51 && weatherCode <= 67) {

        return "🌧️";

    }

    // 雪
    else if (weatherCode >= 71 && weatherCode <= 77) {

        return "❄️";

    }

    // 雷雨
    else if (weatherCode >= 95) {

        return "⛈️";

    }

    // その他
    else {

        return "🌈";

    }

}

APIデータからアイコンを表示する

次に、fetchWeather()へアイコン表示処理を追加します。

script.js

async function fetchWeather() {

    const response = await fetch(apiUrl);

    const data = await response.json();


    // 現在の天気データ
    const current = data.current;


    // 天気アイコンを取得
    const weatherIcon =
        getWeatherIcon(
            current.weather_code
        );


    // アイコンを表示
    weatherIconElement.textContent =
        weatherIcon;

}

コード解説

関数を分ける理由

今回、

getWeatherDescription()

getWeatherIcon()

という2つの関数を作りました。

どちらも同じweather_codeを利用していますが、役割が違います。

関数 役割
getWeatherDescription() 天気コード → 天気名
getWeatherIcon() 天気コード → アイコン

このように、1つの関数に多くの役割を持たせず、役割ごとに分けることでコードが管理しやすくなります。


戻り値

return "☀️";

returnを使うことで、関数の結果としてアイコンを返しています。

例えば、

const icon = getWeatherIcon(0);

の場合、

icon

には、

☀️

が保存されます。


同じデータを複数の処理で利用する

今回、

current.weather_code

を、

  • 天気名の変換
  • アイコンの変換

の2箇所で利用しています。

APIから取得したデータをそのまま使い回し、必要な形へ変換するという考え方は、Webアプリ開発でよく使われます。


このステップで覚えること

  • データ変換処理は関数に分けると管理しやすい
  • 1つのデータを複数の表示へ利用できる
  • APIのデータを画面表示用へ加工する流れを理解する

動作確認

ブラウザを更新してください。

現在の天気カードのアイコンが、APIの天気情報に合わせて変化すれば成功です。

例:

晴れの場合

☀️

30℃

湿度:60%

晴れ

雨の場合

🌧️

22℃

湿度:80%

雨

Phase4 Step3.png

のようになります。


Phase4 Step3のまとめ

今回は、APIから取得したweather_codeを利用して、天気アイコンを自動で切り替える処理を実装しました。

これで現在の天気カードは、

  • 気温
  • 湿度
  • 天気
  • アイコン

すべてがAPIのデータをもとに表示されるようになりました。

次のフェーズでは、週間予報データを取得し、7日間の天気をAPIから表示できるようにしていきます。

Phase5 週間予報

Step1 週間予報データをAPIから取得しよう

前のフェーズでは、現在の天気情報をAPIから取得し、

  • 気温
  • 湿度
  • 天気
  • 天気アイコン

を画面へ表示できるようになりました。

今回は、さらに機能を拡張して週間予報データをAPIから取得する処理を実装します。

現在の天気はcurrentというデータから取得しましたが、週間予報はdailyという別のデータに保存されています。

まずはAPIから週間予報データを取り出せるようにしていきます。


このステップの目標

  • APIのdailyデータを取得する
  • 配列形式の週間予報データを理解する
  • 取得したデータをConsoleで確認する

APIの週間予報データを確認する

Open-Meteo APIでは、週間予報データは以下のような形式で返されます。

daily: {

    time: [
        "2026-08-02",
        "2026-08-03",
        "2026-08-04"
    ],

    weather_code: [
        0,
        3,
        61
    ],

    temperature_2m_max: [
        32,
        30,
        27
    ],

    temperature_2m_min: [
        24,
        23,
        22
    ]

}

それぞれの配列は、同じ日付のデータを順番に持っています。

例えば、

daily.time[0]

は、

2026-08-02

を表します。

また、

daily.temperature_2m_max[0]

は、

32℃

という意味になります。


script.jsを編集する

fetchWeather()内に、週間予報データを取得する処理を追加します。

script.js

async function fetchWeather() {

    // APIへリクエスト
    const response = await fetch(apiUrl);

    // JSONへ変換
    const data = await response.json();


    // 現在の天気
    const current = data.current;


    // 週間予報データを取得
    const daily = data.daily;


    // 確認用
    console.log(daily);

}

コード解説

data.daily

const daily = data.daily;

APIから取得したJSONの中から、

daily

だけを取り出しています。

現在の天気では、

data.current

を使用しました。

今回は、

data.daily

を使用します。


配列

temperature_2m_max: [
    32,
    30,
    27
]

週間予報のデータは配列で管理されています。

配列は、複数の値を順番に保存できるデータ形式です。

例えば、

daily.temperature_2m_max[0]

では、

1日目の最高気温

を取得できます。


インデックス番号

[0]

は配列の最初のデータを取得する指定です。

JavaScriptでは配列の番号は0から始まります。

[
    "",
    "",
    ""
]

の場合、

番号
0
1
2

となります。


このステップで覚えること

  • APIでは現在の天気と週間予報で取得場所が違う
  • dailyには週間予報データが配列で保存されている
  • 配列は[番号]で指定してデータを取得できる

動作確認

ブラウザを更新し、開発者ツールのConsoleを確認してください。

以下のようなデータが表示されれば成功です。

{
    time: Array(7),
    weather_code: Array(7),
    temperature_2m_max: Array(7),
    temperature_2m_min: Array(7)
}

Phase5 Step1.png

をクリックして展開すると、7日分のデータが入っていることを確認できます。


Phase5 Step1のまとめ

今回は、APIから週間予報データを取得する処理を実装しました。

現在の天気はcurrent、週間予報はdailyから取得するという、APIデータの構造を理解できました。

また、週間予報のような複数データを扱う場合、配列を使って管理されることが多いことも学びました。

次のステップでは、取得した週間予報データを使って、JavaScriptで予報カードを自動生成していきます。

Step2 APIのデータから週間予報カードを生成する

前のステップでは、Open-Meteo APIから週間予報データを取得できるようになりました。

今回は、そのデータを利用して、週間予報カードをJavaScriptで自動生成します。

Phase2ではダミーデータを使ってカードを作成しました。

今回は実際のAPIデータを利用することで、

APIから取得した7日分のデータ

↓

JavaScriptでカード生成

↓

画面へ表示

という、実際のWebアプリで使われる流れを実装します。


このステップの目標

  • APIから取得した配列データを利用する
  • 週間予報カードを動的に生成する
  • 繰り返し処理で複数データを表示する

script.jsを編集する

まず、週間予報カードを生成する関数を追加します。

script.js

/* ==========================
   週間予報カード生成
========================== */

function displayWeeklyForecast(daily) {


    // 表示エリアを初期化
    forecastListElement.innerHTML = "";


    // 7日分繰り返す
    for (let i = 0; i < daily.time.length; i++) {


        // 天気アイコン取得
        const icon =
            getWeatherIcon(
                daily.weather_code[i]
            );


        // カード生成
        forecastListElement.innerHTML += `

            <div class="forecast-card">

                <p>
                    ${daily.time[i]}
                </p>


                <div class="forecast-icon">
                    ${icon}
                </div>


                <p>
                    ${daily.temperature_2m_max[i]}℃
                </p>


                <p>
                    最低 ${daily.temperature_2m_min[i]}℃
                </p>

            </div>

        `;

    }

}

API取得処理から関数を呼び出す

次に、fetchWeather()内で作成したdailyデータを渡します。

script.js

async function fetchWeather() {

    const response = await fetch(apiUrl);

    const data = await response.json();


    // 現在の天気
    const current = data.current;


    // 週間予報
    const daily = data.daily;


    // 週間予報を表示
    displayWeeklyForecast(daily);

}

コード解説

関数へデータを渡す

displayWeeklyForecast(daily);

関数を呼び出すときに、取得した週間予報データを渡しています。

渡されたデータは、

function displayWeeklyForecast(daily)

dailyで受け取ります。

このように、処理に必要なデータだけを関数へ渡すことで、コードを整理できます。


for文で7日分処理する

for (let i = 0; i < daily.time.length; i++)

週間予報は7日分あるため、繰り返し処理を使います。

例えば、

i = 0

の場合は1日目、

i = 1

の場合は2日目、

というように順番に処理します。


配列からデータを取得する

daily.temperature_2m_max[i]

配列の番号を指定することで、その日のデータを取得できます。

例えば、

i = 0

なら、

daily.temperature_2m_max[0]

となり、1日目の最高気温を取得できます。


innerHTML +=

forecastListElement.innerHTML += `
    ...
`;

+=を使うことで、既存のHTMLへ追加できます。

今回の場合、

1回目のループ

月曜日カード

2回目のループ

火曜日カード

のように、順番にカードを追加しています。


このステップで覚えること

  • APIデータを関数へ渡して処理できる
  • 配列とfor文を使って複数データを表示できる
  • 実際のデータからHTMLを動的生成する流れを理解する

動作確認

ブラウザを更新してください。

週間予報エリアに、APIから取得した7日分のカードが表示されれば成功です。

例:

週間予報

┌────┐ ┌────┐ ┌────┐
│8/2 │ │8/3 │ │8/4 │
│☀️  │ │☁️  │ │🌧️  │
│32℃│ │30℃│ │27℃│
│24℃│ │23℃│ │22℃│
└────┘ └────┘ └────┘

Phase5 Step2.png

天気や気温は現在の場所・時間によって変化します。


Phase5 Step2のまとめ

今回は、APIから取得した週間予報データを使って、カードを自動生成しました。

これで、

  • 現在の天気
  • 週間予報

の両方がAPIデータから表示されるようになりました。

次のフェーズでは、都市名を入力して検索できるようにし、好きな場所の天気を取得できるアプリへ進化させます。

Phase6 検索機能

Step1 入力された都市名で天気を検索する準備をしよう

前のフェーズでは、Open-Meteo APIから取得したデータを使って、現在の天気と週間予報を表示できるようになりました。

しかし、現在のアプリでは、

latitude=35.6812
longitude=139.7671

のように東京駅周辺の緯度・経度を直接指定しています。

そのため、他の都市を検索することができません。

今回は、検索バーに入力された都市名を取得し、入力した都市の天気を取得するための準備をします。

このステップではまだ緯度・経度の取得は行いません。

まずは、

入力

↓

JavaScriptで取得

↓

検索処理を実行

という流れを作ります。


このステップの目標

  • 入力フォームの値を取得する
  • ボタンのクリックイベントを設定する
  • 検索処理を関数として分離する

HTMLを確認する

Phase1で作成した検索バーには、以下のようなHTMLがあります。

index.html

<div class="search-area">

    <input
        id="city-input"
        type="text"
        placeholder="都市名を入力"
    >

    <button id="search-button">
        検索
    </button>

</div>

今回は、この

id="city-input"

id="search-button"

をJavaScriptから操作します。


script.jsを編集する

まず、検索に必要なHTML要素を取得します。

script.js

/* ==========================
   Phase6 Step1
   検索機能準備
========================== */


// 都市名入力欄
const cityInputElement =
    document.getElementById("city-input");


// 検索ボタン
const searchButtonElement =
    document.getElementById("search-button");

次に、検索ボタンがクリックされた時の処理を追加します。

/* ==========================
   検索処理
========================== */

searchButtonElement.addEventListener(
    "click",
    () => {


        // 入力された都市名を取得
        const cityName =
            cityInputElement.value;


        // 確認
        console.log(cityName);


    }
);

コード解説

value

cityInputElement.value

valueは、入力フォームに入力された文字を取得するプロパティです。

例えば、

入力欄に

Tokyo

と入力した場合、

cityInputElement.value

は、

Tokyo

になります。


addEventListener

searchButtonElement.addEventListener(
    "click",
    () => {

    }
);

addEventListener()は、HTML要素にイベントを追加するメソッドです。

今回は、

"click"

を指定しているため、

検索ボタンをクリックした時

に処理が実行されます。


アロー関数

() => {

}

これはアロー関数という関数の書き方です。

通常の関数では、

function(){

}

と書きますが、

短く書けるため、イベント処理ではよく使われます。


検索処理を関数化する

今後、検索処理は複数の処理を行います。

例えば、

都市名取得

↓

緯度・経度取得

↓

天気API取得

↓

画面更新

です。

そのため、専用の関数を作成します。

script.js

/* ==========================
   都市検索関数
========================== */

function searchWeather(cityName) {


    console.log(
        `${cityName}の天気を検索します`
    );


}

そして、クリックイベントを変更します。

searchButtonElement.addEventListener(
    "click",
    () => {


        const cityName =
            cityInputElement.value;


        searchWeather(cityName);


    }
);

コード解説

関数へデータを渡す

searchWeather(cityName);

このように、関数へデータを渡すことができます。

渡した値は、

function searchWeather(cityName)

の引数として受け取ります。


処理を分ける理由

今回、

searchWeather()

という関数を作りました。

これは、今後処理が増えても管理しやすくするためです。

悪い例:

クリック処理の中に

API取得

JSON解析

画面更新

全部を書く

良い例:

クリック処理

↓

検索関数

↓

API取得関数

↓

表示関数

のように役割を分ける。


このステップで覚えること

  • valueで入力フォームの値を取得できる
  • addEventListener()でクリックイベントを設定できる
  • 処理ごとに関数を分けるとコードを管理しやすい

動作確認

ブラウザを更新してください。

検索欄へ、

Tokyo

など入力して検索ボタンを押します。

開発者ツールのConsoleに、

Tokyo

または、

Tokyoの天気を検索します

Phase6 Step1.png

と表示されれば成功です。

まだ天気情報は変化しません。


Phase6 Step1のまとめ

今回は、都市名検索機能の土台を作成しました。

検索欄から入力された都市名を取得し、クリックイベントで検索処理を実行できるようになりました。

次のステップでは、入力された都市名を使ってGeocoding APIから緯度・経度を取得する処理を実装します。

これにより、ユーザーが入力した好きな都市の天気を取得できるようになります。

Step2 都市名から緯度・経度を取得しよう(Geocoding API)

前のステップでは、検索欄に入力された都市名を取得し、検索処理を実行できるようにしました。

しかし、天気API(Open-Meteo API)は、

東京
大阪
福岡

のような都市名ではなく、

latitude(緯度)

longitude(経度)

を使って天気データを取得します。

そのため、まずは都市名を緯度・経度へ変換する必要があります。

そこで今回は、Open-Meteo Geocoding APIを利用して、

都市名

↓

緯度・経度

↓

天気APIへ渡す

という流れを作ります。


このステップの目標

  • Geocoding APIの役割を理解する
  • 都市名から緯度・経度を取得する
  • API通信を関数として分離する

Geocoding APIとは?

Geocoding APIは、

住所や都市名から位置情報を取得するAPI

です。

例えば、

Tokyo

を送信すると、

{
    latitude: 35.6762,
    longitude: 139.6503
}

のようなデータが返ってきます。

この緯度・経度を天気APIへ渡すことで、その場所の天気を取得できます。


Geocoding APIのURLを作成する

Open-MeteoのGeocoding APIは以下の形式です。

https://geocoding-api.open-meteo.com/v1/search?name=都市名

例えば、

Tokyo

を検索する場合、

https://geocoding-api.open-meteo.com/v1/search?name=Tokyo

へアクセスします。


script.jsを編集する

まず、都市名から緯度・経度を取得する関数を作成します。

script.js

/* ==========================
   Geocoding API
   都市名 → 緯度・経度
========================== */

async function getCoordinates(cityName) {


    // API URL作成
    const url =
        `https://geocoding-api.open-meteo.com/v1/search?name=${cityName}`;


    // APIへリクエスト
    const response =
        await fetch(url);


    // JSONへ変換
    const data =
        await response.json();


    console.log(data);


}

次に、検索処理から呼び出します。

script.js

function searchWeather(cityName) {


    getCoordinates(cityName);


}

コード解説

テンプレートリテラルでURLを作る

`...?name=${cityName}`

${}を使うことで、変数を文字列の中へ埋め込めます。

例えば、

cityName = "Tokyo"

の場合、

https://geocoding-api.open-meteo.com/v1/search?name=Tokyo

になります。


URLパラメータ

?name=Tokyo

この部分はURLパラメータと呼ばれます。

APIへ追加の条件を渡すために使います。

今回の場合、

name

↓

検索する都市名

を指定しています。


JSONデータを確認する

const data =
    await response.json();

前のフェーズでも使用したように、

response.json()

を使うことでAPIから取得したJSONデータをJavaScriptで扱えるようになります。


取得データを確認する

Consoleを見ると、以下のようなデータが表示されます。

{
    results: [
        {
            name: "Tokyo",
            latitude: 35.6762,
            longitude: 139.6503,
            country: "Japan"
        }
    ]
}

この中で必要なのは、

results[0].latitude

results[0].longitude

です。


緯度・経度を取得する

getCoordinates()を以下のように変更します。

script.js

async function getCoordinates(cityName) {


    const url =
        `https://geocoding-api.open-meteo.com/v1/search?name=${cityName}`;


    const response =
        await fetch(url);


    const data =
        await response.json();


    // 検索結果がない場合
    if (!data.results) {

        alert(
            "都市が見つかりません"
        );

        return;

    }


    // 最初の検索結果を取得
    const location =
        data.results[0];


    const latitude =
        location.latitude;


    const longitude =
        location.longitude;


    console.log(latitude);

    console.log(longitude);

}

コード解説

if (!data.results)

if (!data.results)

取得結果が存在するか確認しています。

例えば、

存在する場合

data.results

検索結果あり

存在しない場合

undefined

になります。


return

return;

returnだけを書くと、

そこで関数の処理を終了する

という意味になります。

今回は都市が見つからなかった場合、それ以降の処理を実行しないようにしています。


配列の最初のデータを取得

data.results[0]

APIの検索結果は配列で返されます。

例えば、

results:[
    東京,
    Tokyo,
    東京都
]

の場合、

results[0]

で最初の結果を取得できます。


このステップで覚えること

  • Geocoding APIで都市名を緯度・経度へ変換できる
  • APIごとに必要なデータ形式が違う
  • 配列から取得したいデータを取り出せる

動作確認

ブラウザを更新してください。

検索欄へ、

Tokyo

と入力して検索します。

Consoleに、

35.6762

139.6503

Phase6 Step2.png

のような緯度・経度が表示されれば成功です。


Phase6 Step2のまとめ

今回は、Geocoding APIを利用して都市名から緯度・経度を取得する処理を実装しました。

これで、

都市名

↓

緯度・経度

↓

天気API

という天気検索アプリに必要な基本的な流れが完成しました。

次のステップでは、取得した緯度・経度を使って、検索した都市の天気情報を画面へ表示します。

Step3 検索した都市の天気を表示しよう

前のステップでは、Geocoding APIを利用して、

都市名

↓

緯度・経度

へ変換できるようになりました。

しかし、現在はConsoleに緯度・経度を表示しているだけで、実際の天気情報はまだ東京駅周辺のままです。

今回は取得した緯度・経度を天気APIへ渡し、検索した都市の天気を画面へ表示する処理を実装します。

これで、

都市名入力

↓

緯度・経度取得

↓

天気API取得

↓

画面更新

という一連の流れが完成します。


このステップの目標

  • 緯度・経度を使って天気APIを呼び出す
  • API URLを動的に作成する
  • 検索した都市の天気を表示する

天気API取得処理を関数化する

現在のapiUrlは東京固定になっています。

const apiUrl =
"https://api.open-meteo.com/v1/forecast?latitude=35.6812...";

これでは他の都市を検索できません。

そこで、緯度・経度を受け取ってAPI URLを作成する関数を作ります。


script.jsを編集する

以下の関数を追加してください。

script.js

/* ==========================
   天気API取得
   緯度・経度 → 天気データ
========================== */

async function getWeatherData(latitude, longitude) {


    // 緯度・経度からAPI URL作成
    const url =
        `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,relative_humidity_2m,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min`;


    // APIへリクエスト
    const response =
        await fetch(url);


    // JSONへ変換
    const data =
        await response.json();


    return data;

}

Geocoding APIから天気取得へつなげる

次に、getCoordinates()を変更します。

script.js

async function getCoordinates(cityName) {


    const url =
        `https://geocoding-api.open-meteo.com/v1/search?name=${cityName}`;


    const response =
        await fetch(url);


    const data =
        await response.json();


    if (!data.results) {

        alert(
            "都市が見つかりません"
        );

        return;

    }


    const location =
        data.results[0];


    const latitude =
        location.latitude;


    const longitude =
        location.longitude;


    // 天気データ取得
    const weatherData =
        await getWeatherData(
            latitude,
            longitude
        );


    console.log(weatherData);

}

検索した天気を画面へ表示する

次に、現在の天気表示処理を関数化します。

script.js

/* ==========================
   現在の天気表示
========================== */

function displayCurrentWeather(current) {


    // 気温表示
    temperatureElement.textContent =
        `${current.temperature_2m}℃`;


    // 湿度表示
    humidityElement.textContent =
        `湿度:${current.relative_humidity_2m}%`;


    // 天気表示
    weatherDescriptionElement.textContent =
        getWeatherDescription(
            current.weather_code
        );


    // アイコン表示
    weatherIconElement.textContent =
        getWeatherIcon(
            current.weather_code
        );

}

そして、getCoordinates()の最後を変更します。

script.js

const weatherData =
    await getWeatherData(
        latitude,
        longitude
    );


// 現在の天気を表示
displayCurrentWeather(
    weatherData.current
);

コード解説

関数の役割分担

今回、処理を3つの関数へ分けました。

関数 役割
getCoordinates() 都市名から緯度・経度取得
getWeatherData() 天気APIからデータ取得
displayCurrentWeather() 画面へ表示

このように役割ごとに分割すると、

  • 修正しやすい
  • エラー箇所を探しやすい
  • 機能追加しやすい

というメリットがあります。


引数でデータを渡す

getWeatherData(
    latitude,
    longitude
);

関数へ必要なデータを渡しています。

受け取る側では、

async function getWeatherData(latitude, longitude)

として利用できます。


return data

return data;

取得した天気データを呼び出し元へ返しています。

そのため、

const weatherData =
    await getWeatherData();

のように結果を受け取れます。


検索処理を実行する

最後に、検索ボタンの処理を確認します。

script.js

searchButtonElement.addEventListener(
    "click",
    () => {


        const cityName =
            cityInputElement.value;


        getCoordinates(cityName);


    }
);

これで、

検索ボタンを押す

都市名取得

緯度・経度取得

天気取得

画面更新

という流れになります。


このステップで覚えること

  • API URLは取得したデータから動的に作成できる
  • 複数の処理は役割ごとに関数へ分割すると管理しやすい
  • API取得→加工→表示というWebアプリの基本構造を理解できる

動作確認

ブラウザを更新してください。

検索欄へ、

Tokyo

と入力して検索します。

すると、

☀️

30℃

湿度:60%

晴れ

Phase6 Step3(1).png

のように、検索した都市の天気が表示されます。

さらに、

Osaka

Fukuoka

Sapporo

など別の都市でも試してください。

Phase6 Step3(2).png

都市ごとに天気が変われば成功です。


Phase6 Step3のまとめ

今回は、検索した都市の天気を取得して画面へ表示する処理を実装しました。

これで天気予報アプリの主要機能である、

  • 都市検索
  • 現在の天気表示
  • 天気アイコン変更

が完成しました。

次のフェーズでは、コードを整理し、エラー処理やユーザー体験を改善して、より実際のアプリに近づけていきます。

Phase7 UX改善

Step1 try...catchを使ってエラーハンドリングを実装しよう

前のフェーズでは、都市名を入力すると、

都市名入力

↓

緯度・経度取得

↓

天気API取得

↓

画面更新

という流れで、検索した都市の天気を表示できるようになりました。

しかし、現在のアプリにはまだ問題があります。

例えば、

  • 存在しない都市名を入力する
  • インターネット接続が切れる
  • API側でエラーが発生する

といった場合、ユーザーには何も表示されず、Consoleにエラーが出るだけです。

実際のアプリでは、エラーが発生した場合でもユーザーへ分かりやすく伝える必要があります。

今回は、JavaScriptのtry...catchを使ってエラー処理を追加します。


このステップの目標

  • try...catchの役割を理解する
  • API通信エラーを処理する
  • ユーザーへエラーメッセージを表示する

try...catchとは?

try...catchは、

エラーが発生する可能性がある処理を安全に実行するための構文

です。

基本的な形は以下です。

try {

    // エラーが発生する可能性がある処理

} catch(error) {

    // エラー発生時の処理

}

流れとしては、

try内を実行

↓

成功

↓

そのまま続行


失敗

↓

catchを実行

になります。


API取得処理にエラー処理を追加する

まず、getWeatherData()を変更します。

script.js

/* ==========================
   天気API取得
========================== */

async function getWeatherData(latitude, longitude) {


    try {


        // API URL作成
        const url =
            `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,relative_humidity_2m,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min`;


        // APIへリクエスト
        const response =
            await fetch(url);



        // HTTPエラー確認
        if (!response.ok) {

            throw new Error(
                "天気データを取得できませんでした"
            );

        }



        // JSONへ変換
        const data =
            await response.json();



        return data;



    } catch(error) {


        alert(
            error.message
        );


        return null;


    }

}

コード解説

try

try {

}

tryの中には、

エラーが発生する可能性がある処理を書きます。

今回の場合、

  • API通信
  • JSON変換

などが対象になります。


catch

catch(error){

}

try内でエラーが発生すると、

自動的にcatchへ移動します。

例えば、

fetch()

で通信エラーが起きた場合、

catch(error)

が実行されます。


throw new Error()

throw new Error(
    "天気データを取得できませんでした"
);

throwを使うと、

自分でエラーを発生させることができます。

今回は、

response.ok

falseの場合、

API取得失敗として処理しています。


response.ok

response.ok

は、HTTP通信が成功したか確認するプロパティです。

成功の場合:

true

失敗の場合:

false

になります。


Geocoding APIにもエラー処理を追加する

次に、都市検索処理にも追加します。

script.js

async function getCoordinates(cityName) {


    try {


        const url =
            `https://geocoding-api.open-meteo.com/v1/search?name=${cityName}`;


        const response =
            await fetch(url);



        const data =
            await response.json();



        // 検索結果なし
        if (!data.results) {


            throw new Error(
                "都市が見つかりません"
            );


        }



        const location =
            data.results[0];



        const weatherData =
            await getWeatherData(
                location.latitude,
                location.longitude
            );



        if(weatherData){

            displayCurrentWeather(
                weatherData.current
            );

        }



    } catch(error) {


        alert(
            error.message
        );


    }

}

コード解説

エラー処理を関数ごとに分ける

今回、

getCoordinates()

↓

都市検索エラー


getWeatherData()

↓

天気取得エラー

のように、それぞれの関数でエラー処理を行っています。

このようにすると、

どこで問題が発生したのか分かりやすくなります。


nullチェック

if(weatherData){

}

getWeatherData()で失敗した場合、

return null;

を返しています。

そのため、

weatherData

が存在するときだけ画面更新を行っています。


動作確認

正常ケース

検索欄へ、

Tokyo

と入力します。

結果:

☀️

30℃

湿度:60%

晴れ

が表示されれば成功です。


エラーケース① 存在しない都市

検索欄へ、

abcdefg

と入力します。

結果:

都市が見つかりません

というアラートが表示されれば成功です。


エラーケース② 通信エラー

ネットワークを切断して検索すると、

天気データを取得できませんでした

のようなエラー表示になります。


このステップで覚えること

  • try...catchでエラー発生時の処理を書ける
  • throwで自分でエラーを発生させられる
  • API通信では成功・失敗どちらの場合も考える必要がある

Phase7 Step1のまとめ

今回は、try...catchを利用してエラーハンドリングを実装しました。

これにより、

  • 存在しない都市の検索
  • API通信失敗
  • データ取得失敗

などが発生しても、ユーザーへ分かりやすいメッセージを表示できるようになりました。

実際のWebアプリでは、正常時の処理だけではなく、エラーが発生した場合のユーザー体験も非常に重要です。

次のステップでは、innerHTML +=を使ったHTML生成処理を改善し、より実務的なDOM操作へ変更していきます。

Step2 innerHTML +=を改善して、より実務的なコードにしよう

前のステップでは、try...catchを使ってエラー処理を追加しました。

これでAPI通信に失敗した場合でも、ユーザーへ適切なメッセージを表示できるようになりました。

今回は、週間予報カードを生成している部分を改善します。

現在のコードでは、

forecastListElement.innerHTML += `
    <div class="forecast-card">
        ...
    </div>
`;

という書き方をしています。

この方法でも動作しますが、実務では注意点があります。

今回は、より安全で管理しやすいDOM操作を使ったHTML生成へ変更します。


このステップの目標

  • innerHTML +=の問題点を理解する
  • createElement()でHTML要素を作成する
  • DOM操作でカードを生成する

innerHTML +=の問題点

現在のコード:

forecastListElement.innerHTML += `
<div>
    カード内容
</div>
`;

は簡単にHTMLを追加できます。

しかし、内部では毎回、

現在のHTMLを取得

↓

新しいHTMLを追加

↓

HTML全体を再構築

という処理が行われています。

そのため、

  • 大量のデータでは処理が重くなる
  • 既存のイベントが消える場合がある
  • ユーザー入力を含む場合はXSSリスクがある

という問題があります。


createElement()を使う

JavaScriptには、

HTML要素を作成するためのメソッドがあります。

それが、

document.createElement()

です。

例えば、

const div =
    document.createElement("div");

の場合、

以下のような要素が作成されます。

<div></div>

週間予報カード生成処理を変更する

displayWeeklyForecast()を以下のように変更します。

script.js

/* ==========================
   週間予報カード生成
========================== */

function displayWeeklyForecast(daily) {


    // 表示エリアを初期化
    forecastListElement.innerHTML = "";



    // 7日分繰り返す
    for (
        let i = 0;
        i < daily.time.length;
        i++
    ) {



        // カード要素を作成
        const card =
            document.createElement("div");



        // CSSクラスを追加
        card.classList.add(
            "forecast-card"
        );



        // 天気アイコン取得
        const icon =
            getWeatherIcon(
                daily.weather_code[i]
            );



        // カード内容を設定
        card.innerHTML = `

            <p>
                ${daily.time[i]}
            </p>


            <div class="forecast-icon">

                ${icon}

            </div>


            <p>
                ${daily.temperature_2m_max[i]}℃
            </p>


            <p>
                最低 ${daily.temperature_2m_min[i]}℃
            </p>

        `;



        // カードを追加
        forecastListElement.appendChild(card);


    }

}

コード解説

document.createElement()

document.createElement("div");

新しいHTML要素をJavaScriptから作成できます。

例えば、

document.createElement("p");

なら、

<p></p>

が作成されます。


classList.add()

card.classList.add(
    "forecast-card"
);

HTML要素へCSSクラスを追加するメソッドです。

作成された要素は、

<div class="forecast-card">

</div>

になります。


appendChild()

forecastListElement.appendChild(card);

作成した要素をHTMLへ追加します。

流れは、

createElement()

↓

要素作成

↓

class追加

↓

appendChild()

↓

画面へ追加

になります。


innerHTMLを完全になくさない理由

今回、

card.innerHTML = `
    ...
`;

は残しています。

これは、

作成したカード内部のHTMLを設定するためです。

完全にDOM操作だけで書くこともできますが、

createElement()

appendChild()

textContent()

を大量に書く必要があり、コード量が増えます。

実務では、

  • 静的なHTML → innerHTML
  • 要素追加 → createElement

のように使い分けることも多いです。


セキュリティについて

例えばユーザー入力を、

element.innerHTML =
    userInput;

のように直接HTMLへ入れると危険です。

悪意あるHTMLやJavaScriptが実行される可能性があります。

これを、

XSS
(クロスサイトスクリプティング)

と呼びます。

今回の週間予報データはAPIから取得した安全なデータなので問題ありませんが、

ユーザー入力を扱う場合は注意が必要です。


このステップで覚えること

  • innerHTML +=は簡単だが大量処理では注意が必要
  • createElement()でHTML要素をJavaScriptから作成できる
  • appendChild()で作成した要素を画面へ追加できる

動作確認

ブラウザを更新してください。

確認する内容:

  • 週間予報カードが正常に表示される
  • 天気アイコンが表示される
  • 気温データが表示される

以前と同じ見た目で表示されれば成功です。


Phase7 Step2のまとめ

今回は、週間予報カード生成処理を改善しました。

innerHTML +=から、

createElement()

↓

class追加

↓

appendChild()

というDOM操作へ変更することで、より実務的で拡張しやすいコードになりました。

これで、

  • API通信
  • 非同期処理
  • DOM操作
  • エラー処理
  • 動的UI生成

など、Webアプリ開発で頻出する技術を一通り使った天気予報アプリが完成しました。

次のステップでは、完成したアプリをさらに発展させるための機能追加やリファクタリングに挑戦できます。

まとめ

完成

完成イメージ.png

完成イメージ(クラス早わかり).png

振り返り

今回は、JavaScriptを使って天気予報表示アプリをハンズオン形式で開発しました。

最初は固定されたデータを表示するだけの状態から始め、最終的にはAPIを利用して、好きな都市の天気を検索できるWebアプリへ発展させました。

今回使用した主な技術は以下の通りです。

  • JavaScript

    • DOM操作によるHTMLの動的変更
    • fetch()を使ったAPI通信
    • async / awaitによる非同期処理
    • 配列やオブジェクトを利用したデータ処理
    • try...catchによるエラーハンドリング
  • Web API

    • Open-Meteo APIを利用した天気データ取得
    • Geocoding APIを利用した都市名から緯度・経度の取得
  • フロントエンド開発

    • APIから取得したデータを画面へ反映する流れ
    • JavaScriptによるHTML要素の生成
    • ユーザー操作に応じた画面更新

今回の開発を通して、Webアプリ開発で重要な、

ユーザー入力

↓

APIへリクエスト

↓

データ取得

↓

データ加工

↓

画面へ表示

という基本的な流れを実践的に学ぶことができました。

また、単に動くアプリを作るだけではなく、

  • 処理ごとに関数を分ける
  • エラー発生時の対応を考える
  • 保守しやすいコードを書く

といった、実際の開発現場でも重要になる考え方にも触れました。


今後つけたい拡張機能

🌱 Level1:基本的な機能追加

まずは、現在のアプリをさらに便利にする機能です。

1. 日付表示を改善する

現在は、

2026-08-02

のような形式で表示されています。

これを、

8月2日(日)

のように日本人が見やすい形式へ変更します。

2. 現在地の天気取得

ブラウザの位置情報APIを利用して、

現在地を取得

↓

現在地の天気表示

ができるようにします。

3. ローディング表示

API通信中に、

読み込み中...

のような表示を追加します。

ユーザーに処理中であることを伝えることで、より自然なアプリになります。


🚀 Level2:UI・UX改善

アプリの使いやすさを向上させる機能です。

1. 天気に合わせた背景変更

例えば、

晴れ → 青空の背景

雨 → 雨の日の背景

雪 → 雪景色

のように、天気に合わせてデザインを変更します。

2. レスポンシブ対応

スマートフォンでも使いやすいように、

  • カード配置変更
  • ボタンサイズ調整
  • 画面幅への対応

を行います。

3. 検索履歴機能

過去に検索した都市を保存し、

最近検索した都市

東京
大阪
福岡

のように簡単に再検索できるようにします。


🔥 Level3:実践的なWebアプリ化

より実務に近い機能追加です。

1. TypeScript化

JavaScriptからTypeScriptへ移行します。

型を追加することで、

  • バグの早期発見
  • コード補完の強化
  • 大規模開発への対応

ができます。

2. React / Next.js化

現在はHTML・CSS・JavaScriptで作成していますが、

ReactやNext.jsを利用すると、

  • コンポーネント管理
  • 状態管理
  • 再利用可能なUI作成

など、現代的なフロントエンド開発を学べます。

3. 天気通知機能

ユーザーが設定した都市について、

明日は雨なので傘を持っていきましょう

気温が低いため防寒対策がおすすめです

のような通知機能を追加します。


🏆 Level4:サービスレベルへの発展

実際に公開できるサービスを目指す拡張です。

1. ユーザー認証機能

ログイン機能を追加し、

  • お気に入り都市保存
  • 個人設定保存
  • 複数端末同期

などを可能にします。

2. データベース連携

データベースを導入して、

  • ユーザー情報
  • 検索履歴
  • お気に入り都市

を保存できるようにします。

3. PWA対応

スマホアプリのように、

  • ホーム画面追加
  • オフライン利用
  • プッシュ通知

などに対応します。


おわりに

今回は、JavaScriptを使って天気予報表示アプリを一から作成しました。

最初は単純な画面表示から始まりましたが、API通信や非同期処理、DOM操作などを組み合わせることで、実際に利用できるWebアプリへ発展させることができました。

Web開発では、最初から完璧なアプリを作る必要はありません。

今回のように、

最低限動くものを作る

↓

機能を追加する

↓

コードを改善する

↓

より良いサービスへ成長させる

という流れで開発していくことが重要です。

ぜひ今回作成した天気予報アプリをベースに、自分だけの機能を追加して、さらに発展させてみてください。

このハンズオンが、Webアプリ開発の楽しさを知るきっかけになれば嬉しいです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?