Problem: How can I correctly validate an array of JSON objects sent via an API request?
Situation:
I sent a post request of an array of JSON objects to be saved. However, I cant make the validation work.
JSON
{
"answers": [
{
"title": "hello World",
"question_id": "1"
},
{
"title": "hello World 2",
"question_id": "2"
}
]
}
Attempt #1
Route::post('answer/multiple', function (Request $request) {
$answers = $request->answers;
foreach ($answers as $answer) {
$answer->validate([
'title' => 'required',
'question_id' => 'required',
]);
$new_answer = new Answer();
$new_answer->title = $answer['title'];
$new_answer->question_id = $answer['question_id'];
$new_answer->save();
}
return response()->json($request);
});
I also tried looping through each one to validate, sadly it does not work.
Attempt #2
Route::post('answer/multiple', function (Request $request) {
$validator = Validator::make($request->all(), [
'answer.*.title' => 'required',
'answer.*.question_id' => 'required',
]);
$answers = $request->answers;
foreach ($answers as $answer) {
$new_answer = new Answer();
$new_answer->title = $answer['title'];
$new_answer->question_id = $answer['question_id'];
$new_answer->save();
}
return response()->json($request);
});
In this one, the validation is ignored.
Unlike the $this->validate()
controller method, the Validator::make()
static function will not throw an error if validation fails.
You will need to check if it has failed and return the error messages using the ->fails()
Validator method:
$validator = Validator::make($request->all(), [
'answer.*.title' => 'required',
'answer.*.question_id' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
foreach ($request->answers as $answer) {
$new_answer = new Answer();
$new_answer->title = $answer['title'];
$new_answer->question_id = $answer['question_id'];
$new_answer->save();
}
return response()->json($request);
Alternatively, you can use the $this->validate()
method:
$validatedData = $this->validate($request, [
'answer.*.title' => 'required',
'answer.*.question_id' => 'required',
]);
Note that we use $request
instead of $request->all()
.
Also note that when using this method, you will get an array of answers in $validatedData
, so you will need to change your code accordingly.