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

APP JavaScript
スポンサーリンク

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

2日目のテーマは
「API 通信の“実用レベル”を身につける」
ことです。

1日目では、

  • fetch の基本
  • async/await の書き方
  • ローディング表示
  • 通信失敗時の分岐

を学びました。

2日目はここに、

  • 入力バリデーションの強化
  • API のエラー内容を読み取る
  • UI の状態管理
  • 「成功」「失敗」「ローディング」の 3 状態を整理する

という“実用アプリに必要な要素”を加えていきます。


API 通信アプリの「3つの状態」を理解する

状態1:ローディング中

ユーザーが検索ボタンを押した瞬間から、
API の結果が返ってくるまでの間は
「待っている状態」です。

このときに必要なのは、

  • 「読み込み中…」の表示
  • ボタンの無効化(連打防止)
  • 結果表示エリアのクリア

です。

状態2:成功

API が正常に返ってきたら、

  • 天気情報を表示
  • ステータスに「成功しました」
  • ボタンを再び押せるようにする

という流れになります。

状態3:失敗

失敗にはいくつか種類があります。

  • ネットワークエラー
  • サーバーエラー(500 番台)
  • クライアントエラー(404, 400)
  • API 独自のエラー(都市が見つからないなど)

これらをユーザーにとって意味のあるメッセージに変換します。


入力バリデーションを強化する

なぜ必要なのか?

API 通信は「外部サービス」にアクセスするため、
無効な入力を送ると、

  • 無駄な通信
  • API のエラー
  • ユーザーの混乱

につながります。

バリデーション関数を作る

function validateCity(city) {
  if (!city.trim()) {
    return "都市名を入力してください。";
  }
  if (city.length > 50) {
    return "都市名が長すぎます。50文字以内で入力してください。";
  }
  if (!/^[a-zA-Z\s]+$/.test(city)) {
    return "都市名は英字で入力してください。(例: Tokyo)";
  }
  return null;
}
JavaScript

深掘り:バリデーションは「ユーザーのための安全装置」

エラーを防ぐためではなく、
ユーザーが迷わないためのガイド
だと考えると、より丁寧に作れます。


fetch のエラーを「API の返す JSON」から読み取る

WeatherAPI.com のエラー例

都市名が間違っていると、
API はこんな JSON を返します。

{
  "error": {
    "code": 1006,
    "message": "No matching location found."
  }
}

これを使って、
ユーザーにわかりやすいメッセージを出します。

エラーを読み取る処理

const data = await response.json();

if (data.error) {
  statusDiv.textContent = `エラー:${data.error.message}`;
  return;
}
JavaScript

深掘り:API のエラーは「サーバーが教えてくれるヒント」

HTTP ステータスコードだけではわからない
「都市が見つからない」「API キーが無効」
などの情報を API が返してくれます。

これを活用すると、
ユーザーにとって“優しいアプリ”になります。


ローディング表示を「状態管理」で制御する

状態管理の基本

let isLoading = false;
JavaScript

ローディング開始

function startLoading() {
  isLoading = true;
  statusDiv.textContent = "取得中です…";
  resultDiv.textContent = "";
  searchButton.disabled = true;
}
JavaScript

ローディング終了

function endLoading() {
  isLoading = false;
  searchButton.disabled = false;
}
JavaScript

深掘り:状態管理は「UI の一貫性」を守る

ローディング中にボタンを押せてしまうと、

  • 多重通信
  • API の負荷
  • UI の混乱

が起きます。

状態管理はアプリの安定性を高めます。


2日目の完成コード(重要部分のみ)

const API_KEY = "YOUR_API_KEY";
const baseUrl = "https://api.weatherapi.com/v1/current.json";

const cityInput = document.getElementById("cityInput");
const searchButton = document.getElementById("searchButton");
const statusDiv = document.getElementById("status");
const resultDiv = document.getElementById("result");

function buildUrl(city) {
  const params = new URLSearchParams({
    key: API_KEY,
    q: city,
    lang: "ja"
  });
  return `${baseUrl}?${params.toString()}`;
}

function startLoading() {
  statusDiv.textContent = "天気情報を取得中です…";
  resultDiv.textContent = "";
  searchButton.disabled = true;
}

function endLoading() {
  searchButton.disabled = false;
}

function renderWeather(data) {
  const name = data.location.name;
  const country = data.location.country;
  const temp = data.current.temp_c;
  const text = data.current.condition.text;

  resultDiv.innerHTML = `
    <p>${name} (${country}) の現在の天気</p>
    <p>気温:${temp} ℃</p>
    <p>状況:${text}</p>
  `;
}

async function fetchWeather(city) {
  const error = validateCity(city);
  if (error) {
    statusDiv.textContent = error;
    resultDiv.textContent = "";
    return;
  }

  startLoading();

  try {
    const url = buildUrl(city);
    const response = await fetch(url);

    if (!response.ok) {
      statusDiv.textContent = `サーバーエラーが発生しました。(${response.status})`;
      return;
    }

    const data = await response.json();

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

    statusDiv.textContent = "取得に成功しました。";
    renderWeather(data);

  } catch (error) {
    statusDiv.textContent = "通信に失敗しました。ネットワークを確認してください。";
    console.error(error);

  } finally {
    endLoading();
  }
}

searchButton.addEventListener("click", () => {
  fetchWeather(cityInput.value);
});
JavaScript

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

2日目の本質は、

「API 通信は成功・失敗・ローディングの3状態で考える」
ということです。

そして、

  • fetch は Promise を返す
  • async/await で読みやすく書ける
  • API のエラーは JSON から読み取る
  • ローディング中は UI をロックする
  • バリデーションはユーザーのための安全装置

という“実用アプリの基礎”を身につけました。

ここまで理解できたあなたは、
もう「API を叩ける人」ではなく、
“API を使ってアプリを設計できる人”です。


次の 3 日目では、

  • 複数日の天気(forecast API)
  • 天気アイコンの表示
  • API のレスポンス構造の読み解き
  • UI の改善

など、
さらに“アプリらしさ”を強化していきます。

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