JavaScript | 1 日 120 分 × 7 日アプリ学習:API通信アプリ(WeatherAPI.com)

APP JavaScript
スポンサーリンク

6日目のゴールと今日やること

6日目のテーマは
「API 通信アプリを“より実用的にするための応用力”を身につける」
ことです。

ここまでであなたは、

  • fetch と async/await の基本
  • エラーハンドリングの 3 段階(通信・HTTP・API 独自)
  • ローディング表示
  • 複数日の天気表示
  • UI の改善(アイコン・単位切り替え・履歴・お気に入り)

といった“API 通信アプリの中核”を習得しました。

6日目はここに、

  • 現在地の天気取得(Geolocation API × WeatherAPI)
  • 複数都市の比較表示
  • API 通信の再利用(関数の分割)
  • エラー時のフォールバック処理

を加えて、
「API を使ったアプリを自分で設計できるレベル」
に引き上げます。


現在地の天気を取得する(Geolocation × fetch)

現在地の天気を取る流れ

現在地の天気を取るには、次の 3 ステップです。

  1. Geolocation API で緯度・経度を取得する
  2. WeatherAPI の q に「lat,lon」を渡す
  3. fetch → async/await → エラーハンドリング

つまり、
「位置情報 API」と「天気 API」をつなぐだけ」
です。

Geolocation API の基本

navigator.geolocation.getCurrentPosition(success, error);
JavaScript

success には「位置情報が取れたときの処理」
error には「失敗したときの処理」
を渡します。

位置情報取得 → 天気取得の実装

function getCurrentLocationWeather() {
  showLoading();
  startLoading();

  navigator.geolocation.getCurrentPosition(
    async (pos) => {
      const lat = pos.coords.latitude;
      const lon = pos.coords.longitude;

      try {
        const url = buildUrl(`${lat},${lon}`, 3);
        const response = await fetch(url);

        if (!response.ok) {
          showError(`サーバーエラー(${response.status})`);
          return;
        }

        const data = await response.json();

        if (data.error) {
          showError(`エラー:${data.error.message}`);
          return;
        }

        showStatus("現在地の天気を取得しました。");
        renderForecast(data);

      } catch (err) {
        showError("通信に失敗しました。ネットワークを確認してください。");
      } finally {
        endLoading();
      }
    },

    () => {
      showError("位置情報の取得に失敗しました。許可を確認してください。");
      endLoading();
    }
  );
}
JavaScript

深掘り:API 通信は「入力が変わるだけで同じ型」

都市名 → “Tokyo”
現在地 → “35.6,139.7”

入力が変わるだけで、fetch の書き方は同じ
ということが重要です。


複数都市の天気を比較する

なぜ比較機能を作るのか?

API 通信アプリの応用として、
「複数の都市を同時に表示する」
というのは非常に良い練習になります。

理由は、

  • fetch を複数回呼ぶ
  • Promise の扱いに慣れる
  • UI をループで生成する
  • エラーが都市ごとに発生する可能性がある

という“実践的な課題”が詰まっているからです。

都市の配列を用意する

const compareCities = ["Tokyo", "Osaka", "Sapporo"];
JavaScript

都市ごとに fetch する

async function fetchMultipleCities(cities) {
  showLoading();
  startLoading();

  const results = [];

  for (const city of cities) {
    try {
      const url = buildUrl(city, 1);
      const response = await fetch(url);

      if (!response.ok) {
        results.push({ city, error: `HTTPエラー(${response.status})` });
        continue;
      }

      const data = await response.json();

      if (data.error) {
        results.push({ city, error: data.error.message });
        continue;
      }

      results.push({ city, data });

    } catch (err) {
      results.push({ city, error: "通信エラー" });
    }
  }

  endLoading();
  renderComparison(results);
}
JavaScript

比較結果を表示する

function renderComparison(results) {
  let html = "<h3>都市別の天気比較</h3>";

  results.forEach((item) => {
    if (item.error) {
      html += `<p>${item.city}:エラー(${item.error})</p>`;
      return;
    }

    const temp = item.data.current.temp_c;
    const text = item.data.current.condition.text;
    const icon = "https:" + item.data.current.condition.icon;

    html += `
      <div class="compare-item">
        <h4>${item.city}</h4>
        <img src="${icon}" />
        <p>${temp} ℃</p>
        <p>${text}</p>
      </div>
    `;
  });

  resultDiv.innerHTML = html;
}
JavaScript

深掘り:複数 fetch の本質は「ループ × try-catch」

複数都市を扱うときに大事なのは、

  • 都市ごとに成功・失敗が分かれる
  • 失敗してもアプリ全体は止めない
  • 結果を配列にまとめて最後に描画する

という“実践的なエラーハンドリング”です。


API 通信を「関数に分割」して再利用性を高める

fetchForecast の中身を分割する

fetchForecast は大きく 3 つの役割があります。

  1. URL を作る
  2. fetch して JSON を返す
  3. UI に反映する

これを分割すると、
アプリが一気に読みやすくなります。

API 通信だけを担当する関数

async function getWeatherData(city, days = 3) {
  const url = buildUrl(city, days);
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`HTTPエラー(${response.status})`);
  }

  const data = await response.json();

  if (data.error) {
    throw new Error(data.error.message);
  }

  return data;
}
JavaScript

fetchForecast は「UI の制御だけ」にする

async function fetchForecast(city) {
  const error = validateCity(city);
  if (error) {
    showError(error);
    return;
  }

  showLoading();
  startLoading();

  try {
    const data = await getWeatherData(city, 3);
    showStatus("3日分の天気を取得しました。");
    renderForecast(data);
    addHistory(city);

  } catch (err) {
    showError(err.message);

  } finally {
    endLoading();
  }
}
JavaScript

深掘り:API 通信と UI を分けると「再利用性」が爆上がりする

getWeatherData は
現在地でも
複数都市でも
お気に入りでも
比較機能でも
どこでも使える共通関数になります。

これが中級者の設計です。


エラー時のフォールバック処理を入れる

フォールバックとは?

「失敗したときに代わりの処理をする」
という考え方です。

例:

  • 現在地取得に失敗 → 東京の天気を表示
  • 複数都市の比較で 1 都市だけ失敗 → 他の都市は表示
  • API が落ちている → キャッシュしたデータを表示(今日は簡易版)

現在地取得のフォールバック例

navigator.geolocation.getCurrentPosition(
  success,
  () => {
    showError("位置情報が取得できませんでした。代わりに東京の天気を表示します。");
    fetchForecast("Tokyo");
  }
);
JavaScript

深掘り:フォールバックは「アプリを止めないための技術」

API 通信は外部サービスに依存するため、
失敗することを前提に設計する
のがプロの考え方です。


6日目のまとめ

今日やったことを整理すると、こうなります。

現在地の天気取得(Geolocation × fetch)
複数都市の比較(ループ × try-catch)
API 通信の分割(getWeatherData)
フォールバック処理(失敗時の代替動作)

どれも「新しい文法」ではなく、
fetch・async/await・エラーハンドリングの応用です。


今日いちばん深く理解してほしいこと

6日目の本質は、

「API 通信は“型”を覚えたら、あとは応用で広げられる」
ということです。

fetch
async/await
try-catch
response.ok
data.error

この 5 つの型を守れば、
現在地でも
複数都市でも
お気に入りでも
比較でも
どんな API 通信でも作れます。

あなたはもう、
“API を使ったアプリを設計できる人”
の領域に入っています。


次の 7 日目では、
この天気アプリを「完成版」としてまとめ、

  • ローカルストレージ保存
  • UI の最終調整
  • コードの整理(リファクタリング)

を行い、
中級編の集大成に仕上げていきます。

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