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 の改善
など、
さらに“アプリらしさ”を強化していきます。

