When trying to catch my Laravel validation errors using javascript, it keeps giving me the data in html format rather than json format, my validation looks normal. note i am using vue.js 3 and if the validation passes the actual method in the controller works fine, this is just a validation catching issue.
$request->validate([
'first_name' => ['required', 'string', 'min:3', 'max:255'],
'last_name' => ['required', 'string', 'min:3', 'max:255'],
'email' => ['required', 'email', 'min:3', 'max:255'],
'message' => ['required', 'string', 'min:3']
]);
my fetch method is as follows:
fetch('/contact-us', {
method: 'POST',
headers: {
'CONTENT-TYPE': 'application/json'
},
body: JSON.stringify(this.form)
}).then((response) => response.text())
.then((data) => {
console.log(data);
//data = JSON.parse(data);
}).catch(function(error) {
console.log('Error: ' error);
});
my web route is:
Route::post('/contact-us', [IndexController::class, 'contactForm']);
the error in html format is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link href="/css/app.css" rel="stylesheet" />
<script src="/js/app.js" defer></script>
</head>
<body>
<style>
body{
margin: 0 !important;
overflow-x: hidden;
}
.container {
padding-top: 20px;
}
</style>
<div id="app" data-page="{"component":"ContactUs","props":{"errors":{"email":"The email must be a valid email address."},"csrf":"tFYwkcZZhNfeb2WXDwdnSv4dchujDvSvLfFGhHW1"},"url":"\/contact-us","version":"0f4e2ee0f7e2ca9da665d2f8035743df"}"></div></body>
CodePudding user response:
If validation fails during a traditional HTTP request, a redirect response to the previous URL will be generated.
If the incoming request is an XHR request, a JSON response containing the validation error messages will be returned.
First I suppose that /contact-us is a Web route and not an API route.
The $request->validate()
default behavior on failure is to redirect you to the previous Web route with MessageBag
.
To prevent that default behaviour, you need to wrap the validation process in a try-catch block and catch the Illuminate\Validation\ValidationException
Exception and return error messages from [IndexController::class, 'contactForm']
.
The the error messages array will automatically get converted to a JSON response.
try {
$request->validate([
'first_name' => ['required', 'string', 'min:3', 'max:255'],
'last_name' => ['required', 'string', 'min:3', 'max:255'],
'email' => ['required', 'email', 'min:3', 'max:255'],
'message' => ['required', 'string', 'min:3']
]);
} catch (\Illuminate\Validation\ValidationException $th) {
return $th->validator->errors();
}
Example respone:
{
"first_name": [
"first name field is required."
],
"last_name": [
"last name field is required."
],
"email": [
"L'E-mail field is required."
],
"message": [
"message field is required."
]
}
CodePudding user response:
The laravel docs days the response is given a 422 which throws an error in the usual error catch block. This data can be extracted by adding this catch error to your json post request
.catch(error => {
if (error.response.data.errors) {
console.log(error.response.data.errors);
}
});