JavaScript | 配列・オブジェクト:実務パターン – フォームデータ整形

JavaScript JavaScript
スポンサーリンク

フォームデータ整形とは何か

フォームデータ整形は「UIから入力された生の値(文字列中心・未入力混在・チェックボックスの揺れなど)を、バックエンドが扱いやすい“型の揃ったオブジェクト”に変換する」作業です。ここが重要です:文字列を適切な型(数値・真偽値・日付・配列)に変換し、必須・任意・既定値を明確化し、余計な空白や表記ゆれを正規化する。送信前に“バリデーション→整形→ペイロード作成”の順で処理します。


よくある入力の課題と正規化(トリム・大小・全角半角)

文字列の前処理(必須のベース整形)

const normalizeText = s =>
  s == null ? "" : s.trim();

const normalizeLower = s =>
  normalizeText(s).toLowerCase();

const normalizeFullToHalf = s =>
  normalizeText(s).replace(/[!-~]/g, ch => String.fromCharCode(ch.charCodeAt(0) - 0xFEE0));
JavaScript

ここが重要です:前後空白の除去(trim)は基本。検索語やコード類は小文字化で揺れを減らし、ユーザー入力でありがちな全角英数字は半角に揃える。正規化は“関数に閉じる”と再利用が効きます。

数値の安全変換と欠損の扱い

const toInt = (s, def = null) => {
  const n = Number.parseInt(normalizeFullToHalf(s), 10);
  return Number.isFinite(n) ? n : def;
};

const toFloat = (s, def = null) => {
  const n = Number.parseFloat(normalizeFullToHalf(s));
  return Number.isFinite(n) ? n : def;
};
JavaScript

ここが重要です:空文字は数値にできません。失敗時の既定値(def)を設計し、必要ならエラーにせず“nullで送る”か“バリデーションで弾く”かを決める。

真偽値・チェックボックスの変換

const toBool = v =>
  v === true || v === "true" || v === "on" || v === "1";
JavaScript

ここが重要です:HTMLフォームはチェック時に “on” や “true” などで来ることがある。仕様上の表現を網羅して真偽値に統一する。


型を揃えたオブジェクトへマッピング(フィールドごとの変換)

生入力からペイロードを作る基本パターン

function toPayload(input) {
  return {
    name: normalizeText(input.name),
    email: normalizeText(input.email).toLowerCase(),
    age: toInt(input.age),                      // 失敗時は null(送信先で判断)
    price: toFloat(input.price, 0),            // 失敗時は 0 にする仕様
    active: toBool(input.active),
    tags: toTagsArray(input.tags),             // カンマ区切り→配列へ
    birthday: toIsoDate(input.birthday),       // "YYYY-MM-DD"へ揃える
    note: normalizeText(input.note) || null    // 空なら null に
  };
}

function toTagsArray(s) {
  return normalizeText(s)
    .split(",")
    .map(x => normalizeText(x))
    .filter(x => x.length > 0);
}

function toIsoDate(s) {
  const t = normalizeText(s);
  const d = new Date(t);
  return Number.isNaN(d.getTime()) ? null : d.toISOString().slice(0, 10);
}
JavaScript

ここが重要です:フィールドごとに“入力→変換→既定値”を定義する。空文字のまま送るより、nullで「未入力」を表現するほうがサーバー側で扱いやすい場面が多い。


配列・オブジェクトのフォーム(チェック群・住所・電話)

チェックボックス群→配列(複数選択)

// UI: [{value:"a", checked:true}, {value:"b", checked:false}, ...]
const toSelectedValues = options =>
  options.filter(o => toBool(o.checked)).map(o => String(o.value));
JavaScript

ここが重要です:入力が混在するため、チェック判定は toBool に集約する。値は文字列へ正規化しておくと辞書化しやすい。

住所のネスト整形(空を除外/必須チェック)

function toAddress(input) {
  const addr = {
    zip: normalizeFullToHalf(input.zip),
    prefecture: normalizeText(input.prefecture),
    city: normalizeText(input.city),
    line1: normalizeText(input.line1),
    line2: normalizeText(input.line2) || null
  };
  // 必須チェック(例)
  if (!addr.zip || !addr.prefecture || !addr.city || !addr.line1) {
    return { error: "address_required", value: addr };
  }
  return { value: addr };
}
JavaScript

ここが重要です:ネストは“部分オブジェクト”を作った後に必須検証。失敗時はエラーコード+部分値を返して再入力支援に使う。

電話番号の正規化(数字だけ・国番号)

function toPhone(s, country = "JP") {
  const digits = normalizeFullToHalf(s).replace(/\D/g, "");
  if (!digits) return null;
  if (country === "JP" && digits.length === 10) return `0${digits.slice(1)}`;
  return digits; // 最低限“数字のみ”に
}
JavaScript

ここが重要です:用途次第でフォーマットは変わるが、まずは“数字だけ”に。国別の細かなルールは段階的に拡張する。


ラジオ・セレクトの既定値と不正値(安全なスキーマ)

許可値リストでガードする

const allowedStatus = new Set(["active", "inactive", "pending"]);
const toStatus = s => allowedStatus.has(s) ? s : "pending";
JavaScript

ここが重要です:セレクト値はクライアント側でも“許可値”でガードし、不正値が来たら既定へフォールバック。サーバー側でも同様に検証する二重防御が安全。


バリデーション→整形→エラーの返し方(UXに効く)

段階を分ける(読みやすくテストしやすい)

function validate(input) {
  const errors = {};
  if (!normalizeText(input.name)) errors.name = "required";
  if (!/^\S+@\S+\.\S+$/.test(normalizeText(input.email))) errors.email = "invalid";
  const age = toInt(input.age);
  if (age == null || age < 0) errors.age = "invalid";
  return { ok: Object.keys(errors).length === 0, errors };
}

function shape(input) {
  return toPayload(input);
}

function processForm(input) {
  const v = validate(input);
  if (!v.ok) return { ok: false, errors: v.errors };
  return { ok: true, payload: shape(input) };
}
JavaScript

ここが重要です:検証(validate)と整形(shape)を分離すると見通しが良く、単体テストが簡単になる。エラーはフィールド単位のコードで返し、UIでメッセージに変換する。


実務の細部(空文字の扱い・null/undefined・既定値)

空文字は“未入力”として null に寄せる

const emptyToNull = s => {
  const t = normalizeText(s);
  return t.length ? t : null;
};
JavaScript

ここが重要です:空文字のまま送るとサーバー側の“必須/未入力”判定が難しくなる。未入力を null に統一すると整合が取れる。

nullish coalescing(??)で既定値を一貫適用

function toPayloadSafe(input) {
  return {
    perPage: toInt(input.perPage) ?? 20,
    active: toBool(input.active ?? false),
    q: normalizeText(input.q) ?? ""
  };
}
JavaScript

ここが重要です:?? は null/undefined のみ既定値に置換。0・空文字・falseを尊重したい場面で安全。


ファイル・FormData の取り扱い(アップロード)

FormData からの抽出と型整形

function fromFormData(fd) {
  return {
    name: normalizeText(fd.get("name")),
    age: toInt(fd.get("age")),
    avatar: fd.get("avatar") // File or null
  };
}
JavaScript

ここが重要です:FormData#get は文字列や File を返す。大文字小文字・空白・数値変換はここでも適用。ファイルはそのまま送る(別途サイズや拡張子の検証が必要)。


送信前の最終整形(余計なフィールドを削る・キー順)

送信用にフィールドを限定する

function toApiPayload(p) {
  const { name, email, age, price, active, tags, birthday, note } = p;
  return { name, email, age, price, active, tags, birthday, note };
}
JavaScript

ここが重要です:内部状態にあるUI専用のフラグや計算値を混ぜない。APIに必要なキーだけに絞って送ると、互いの契約が明確になる。


すぐ使えるレシピ(現場の定番)

一括正規化+整形のパイプ

const normalize = {
  text: normalizeText,
  lower: normalizeLower,
  half: normalizeFullToHalf,
  int: toInt,
  float: toFloat,
  bool: toBool
};

function shapeUserForm(f) {
  return {
    name: normalize.text(f.name),
    email: normalize.lower(f.email),
    age: normalize.int(f.age),
    subscribed: normalize.bool(f.subscribed),
    tags: toTagsArray(f.tags),
    birthday: toIsoDate(f.birthday),
    note: emptyToNull(f.note)
  };
}
JavaScript

エラー付き結果(成功ならペイロード/失敗なら理由)

function submitUserForm(raw) {
  const { ok, errors } = validate(raw);
  if (!ok) return { ok: false, errors };
  const payload = shapeUserForm(raw);
  return { ok: true, payload: toApiPayload(payload) };
}
JavaScript

まとめ

フォームデータ整形の核心は「入力の揺れを正規化し、型を明確化し、未入力は null・不正はエラーへ分離する」ことです。文字列は trim・小文字化・全角→半角、数値は安全変換、チェック類は toBool、配列は分割→フィルタで整える。検証(validate)と整形(shape)を別関数にし、送信前に余計なフィールドを落としてペイロードを作る。これを徹底すれば、初心者でも堅牢で読みやすく、実務で信頼できるフォーム処理が書けます。

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