こんにちは。ポチです。
しばらくは毎月1投稿目指してみることにします。
前回の投稿
前回の投稿の最初の画像で、「message は必須です, item は必須です」というバリデーションを出しました。(画像は前回記事より引用)

しかし、実装途中で[object Object]と表示されてしまいました。

前回の振り返りも兼ねて、この原因と解決策を言語化していきたいと思います。
前提
以下のCakePHPでのバリデーションを、Next.jsを使ったフロントで表示しようとしていました。
class EchoMessageValidator
{
public static function getValidator(): Validator
{
$validator = new Validator();
$validator
->requirePresence('message', true, 'message は必須です') // フィールドが存在しない時
->notEmptyString('message', 'message は必須です'); // 空文字列ではないか
$validator
->requirePresence('item', true, 'item は必須です')
->notEmptyString('item', 'item は必須です');
return $validator;
}
}
原因
[object Object]と表示された当時のフロント側コード
const errorList: string[] = [];
if (data.errors?.message) {
errorList.push(data.errors.message);
}
if (data.errors?.item) {
errorList.push(data.errors.item);
}
setErrorMessage(errorList.length > 0 ? errorList.join(", ") : "エラーがあります");
console.log(data.errors)でログを出してみると、中身は以下のようになっています。
オブジェクトがそのままerrorListの配列に追加されてしまった結果、[object Object]と表示されてしまったようです。
解決策
そこで、オブジェクトから文字列を取り出す必要がありました。
解決したコードは下記になります。
const errorList: string[] = [];
if (data.errors?.message) {
errorList.push(...Object.values(data.errors.message));
}
if (data.errors?.item) {
errorList.push(...Object.values(data.errors.item));
}
setErrorMessage(errorList.length > 0 ? errorList.join(", ") : "エラーがあります");
Object.values()はオブジェクトのすべての値を配列として返すメソッドです。
キーを捨ててvalueだけ取得することができます。
また、...はスプレッド演算子です。オブジェクトのすべての値を配列として返し、pushすることで配列に要素を追加します。
今回の場合であれば、
{required: "message は必須です"}の"message は必須です"の部分を取り出して(itemのバリデーション文も同様)、errorListの配列に詰めていたわけですね。
あとがき
記事を書くまでは「配列の外側を見てしまっているんだろうな」というなんとなくの認識でしたが、このように記事にすることで理解が深まりました。
文字に起こしてみるって大事ですね!
また次回の記事でお会いしましょう!
