3日目のゴールと今日やること
3日目のテーマは
「通貨変換アプリを“使っていて気持ちいいツール”に進化させる」 ことです。
1日目でレート取得、2日目で金額変換までできるようになりました。
3日目では、アプリとしての完成度を一気に上げるために、次の機能を追加します。
- 通貨の「逆変換」ボタン(USD→JPY を JPY→USD に一瞬で切り替える)
- よく使う通貨ペアのプリセット(例:JPY→USD、USD→EUR)
- 入力補助(from と to が同じなら自動で変えるなど)
- fetch / async‑await / エラーハンドリングを“設計として整理”する
今日の内容は、初心者がつまずきやすい
「UI と API の連動」 を丁寧に解説していきます。
通貨変換アプリの現状を整理する
あなたのアプリはすでに、
- 金額入力
- from / to 通貨選択
- ExchangeRate.host の
/convertを fetch - async/await で待つ
- try/catch でエラーを受け止める
- ローディング表示
- 通信失敗時の分岐
- レートと変換結果の表示
という、API アプリの基本をすべて備えています。
3日目では、ここに「操作性の向上」を加えていきます。
通貨の「逆変換」ボタンを作る
なぜ必要なのか
ユーザーはよくこう思います。
「USD→JPY を見たあと、JPY→USD も見たい」
そのたびにプルダウンを両方変えるのは面倒です。
そこで 逆変換ボタン を作ります。
ボタンのイメージ
<button id="swapButton">⇄ 逆変換</button>
JavaScript 側で取得します。
const swapButton = document.getElementById("swapButton");
JavaScript逆変換のロジックを作る
from と to を入れ替えるだけ
function swapCurrencies() {
const from = fromSelect.value;
const to = toSelect.value;
fromSelect.value = to;
toSelect.value = from;
statusDiv.textContent = `${to} → ${from} に切り替えました。`;
}
JavaScriptイベント登録:
swapButton.addEventListener("click", swapCurrencies);
JavaScript深掘りポイント
ここで大事なのは、
- 「UI の状態を変えるだけ」
- 「API は呼ばない」
という分離です。
ユーザーが「逆変換したあとに変換ボタンを押す」
という自然な流れを壊さないようにします。
よく使う通貨ペアのプリセットを作る
なぜプリセットが便利なのか
ユーザーは毎回同じ通貨ペアを使うことが多いです。
- JPY → USD
- USD → EUR
- EUR → JPY
これをワンクリックでセットできると、
アプリの使い勝手が一気に上がります。
プリセットボタンのイメージ
<button class="preset" data-from="JPY" data-to="USD">JPY → USD</button>
<button class="preset" data-from="USD" data-to="EUR">USD → EUR</button>
<button class="preset" data-from="EUR" data-to="JPY">EUR → JPY</button>
JavaScript 側で取得します。
const presetButtons = document.querySelectorAll(".preset");
JavaScriptプリセットのロジック
data 属性を使って from / to をセットする
presetButtons.forEach((btn) => {
btn.addEventListener("click", () => {
const from = btn.dataset.from;
const to = btn.dataset.to;
fromSelect.value = from;
toSelect.value = to;
statusDiv.textContent = `${from} → ${to} を選択しました。`;
});
});
JavaScript深掘りポイント
data 属性を使うことで、
- HTML 側でペアを定義
- JS 側は「セットするだけ」
という責任分離ができます。
これは UI 設計の基本です。
入力補助:from と to が同じなら自動で変える
ユーザーがよくやるミス
- from を JPY にした
- to も JPY にした
- 「あれ、変換できない…」
これを防ぐために、
同じ通貨が選ばれたら自動で変える
という補助を入れます。
ロジック
function autoFixSameCurrency() {
if (fromSelect.value === toSelect.value) {
// とりあえず USD に変えるなど
toSelect.value = "USD";
statusDiv.textContent = "同じ通貨が選ばれたため、変換先を USD に変更しました。";
}
}
JavaScriptイベント登録:
fromSelect.addEventListener("change", autoFixSameCurrency);
toSelect.addEventListener("change", autoFixSameCurrency);
JavaScript深掘りポイント
ユーザーが「間違えた」と感じる前に
アプリが先回りして修正してくれると、
使い心地が一気に良くなります。
fetch / async‑await / エラーハンドリングを“設計として整理”する
2日目までの convertCurrency を振り返る
2日目の convertCurrency は、
すでにかなり良い形になっています。
今日は、そこに「UI の改善」を加えます。
3日目版 convertCurrency(完成形)
async function convertCurrency() {
const rawAmount = amountInput.value.trim();
const from = fromSelect.value;
const to = toSelect.value;
if (from === to) {
statusDiv.textContent = "異なる通貨を選択してください。";
resultDiv.textContent = "";
return;
}
const parsed = parseAmount(rawAmount);
if (!parsed.ok) {
statusDiv.textContent = parsed.message;
resultDiv.textContent = "";
return;
}
const amount = parsed.value;
startLoading(`${amount} ${from} → ${to} に変換中です…`);
resultDiv.textContent = "";
try {
const url =
`https://api.exchangerate.host/convert` +
`?from=${encodeURIComponent(from)}` +
`&to=${encodeURIComponent(to)}` +
`&amount=${encodeURIComponent(amount)}`;
const response = await fetch(url);
if (!response.ok) {
if (response.status >= 500) {
statusDiv.textContent = "サーバー側でエラーが発生しています。時間をおいて再試行してください。";
} else {
statusDiv.textContent = `サーバーエラーが発生しました。(${response.status})`;
}
return;
}
const data = await response.json();
if (!data || data.success === false) {
statusDiv.textContent = "レートの取得に失敗しました。";
console.error("API error response:", data);
return;
}
if (typeof data.result !== "number") {
statusDiv.textContent = "予期しない形式のデータが返されました。";
console.error("Unexpected data:", data);
return;
}
statusDiv.textContent = "通貨変換に成功しました。";
renderConversion(from, to, amount, data.result, data.info?.rate);
} catch (error) {
statusDiv.textContent = "通信に失敗しました。ネットワークを確認してください。";
console.error(error);
} finally {
endLoading();
}
}
JavaScript重要ポイント1:try の中は「成功したときのストーリー」にする
try ブロックの中は、
できるだけ「うまくいったときの流れ」だけを書くようにします。
- URL を組み立てる
- fetch でレスポンスを取る
- HTTP ステータスをチェック
- JSON に変換
- API の success をチェック
- result の型をチェック
- 表示する
失敗したときのことは、
HTTP エラーの if と catch に任せます。
重要ポイント2:エラーの“責任の場所”を意識する
エラーは種類ごとに責任を分けると、
コードが読みやすくなります。
入力エラー → parseAmount
HTTP エラー → response.ok
API レベルの失敗 → data.success
データ形式エラー → typeof data.result
ネットワークエラー → catch
この分担ができていると、
あとから読むときにとても楽です。
3日目のまとめ
今日あなたがやったことを整理すると、こうなります。
- 通貨の逆変換ボタンを作った
- よく使う通貨ペアのプリセットを作った
- from と to が同じなら自動で修正する入力補助を入れた
- fetch / async‑await / エラーハンドリングを「設計として整理」した
- convertCurrency をストーリーとして読める形にした
どれも新しい文法ではなく、
「アプリとしての使いやすさを上げるための設計」 です。
今日いちばん深く理解してほしいこと
3日目の本質は、
「API アプリは、fetch のコードを増やすより、UI と入力の設計を整える方が大事」
ということです。
通貨変換アプリは、
fetch → await → JSON → 分岐 → UI
という“型”の上に成り立っています。
4日目では、このアプリに
状態管理(state)・お気に入り通貨ペア・localStorage 保存
などを加えて、さらに“毎日使えるツール”に育てていきます。

