▪️
AngularのsetErrorsで特定のエラーを削除する方法
はじめに
Angularでフォーム開発をしていると、こんな場面に遭遇したことはありませんか?
「特定の条件でのみ発生するバリデーションエラーを削除したいけど、
他のエラーは残しておきたい…」
Angularの標準的な setErrors()
メソッドは、この要求を満たすのが意外と難しいのです。
よくある問題のシナリオ
例えば、商品検索フォームで「価格の範囲」を入力するケースを考えてみましょう。
ユーザーは検索条件として 最小価格(minPrice) と 最大価格(maxPrice) を入力します。
このとき、フォームには次のようなバリデーションが求められます:
- 両方とも必須入力(
required
) - 数値は 0 以上であること(
min
) -
minPrice ≤ maxPrice
でなければならない
問題のある実装
バリデーション要件の3つ目(minPrice ≤ maxPrice
)は、2つの入力欄の関係をチェックするため、カスタムバリデーションが必要になります。そこで「条件を満たせばエラーを消す」という発想で、多くの開発者が最初に書いてしまうのが次のようなコードを書いてしまいます。
// すべてのエラーが削除される
if (minPrice <= maxPrice) {
control.setErrors(null);
}
何が問題なのか?
setErrors(null)
を呼ぶと、そのフィールドのエラーがすべて削除されます。
例えば、以下のように複数のエラーが同時に存在していた場合:
{ required: true, min: true, customError: true }
customError
だけを消したかったのに、required
や min
まで一緒に消えてしまい、
結果として本来表示されるべきエラーメッセージが消えてしまいます。
setErrors(null)
でエラーが消えるのか?
なぜ これはAngularのsetErrorsメソッドの仕様によるものです。
setErrors(
errors: ValidationErrors | null,
opts: { emitEvent?: boolean } = {}
): void
errors
- ValidationErrors型を渡すと、それが現在のエラーとして設定されます。
-
null
を渡すと「エラーなし」とみなされる
解決策:特定のエラーのみを削除する
解決のポイントは次の3ステップです:
- 現在のエラーを取得する
- 消したいエラーだけを削除する
- 残ったエラーを再設定する(空なら
null
を渡す)
実装例
const errors = control.errors || {};
delete errors.customError;
control.setErrors(
Object.keys(errors).length ? errors : null
);
// 結果:{ required: true, min: true } (必要なエラーは保持される)
おわりに
Angularでフォームバリデーションを扱う際、setErrors(null)
を安易に使うと、
意図せず他のエラーまで消えてしまうことがあります。
ポイントは次の2つです:
-
setErrors
は既存エラーをすべて置き換える仕様 - 特定のエラーだけ削除したい場合は 既存エラーを保持して再設定する
このパターンを理解しておけば、複雑なバリデーションでも安全にエラーを制御できます。
Discussion