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="{"ponent":"ContactUs","props":{"errors":{"email":"The email must be a valid email address."},"csrf":"tFYwkcZZhNfeb2WXDwdnSv4dchujDvSvLfFGhHW1"},"url":"\/contact-us","version":"0f4e2ee0f7e2ca9da665d2f8035743df"}"></div></body>
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="{"ponent":"ContactUs","props":{"errors":{"email":"The email must be a valid email address."},"csrf":"tFYwkcZZhNfeb2WXDwdnSv4dchujDvSvLfFGhHW1"},"url":"\/contact-us","version":"0f4e2ee0f7e2ca9da665d2f8035743df"}"></div></body>
Share
Improve this question
asked Feb 19, 2022 at 17:45
sgb999sgb999
792 silver badges9 bronze badges
2
- It's probably a token issue. Do you use Sanctum to authenticate your frontend app? – Bulent Commented Feb 19, 2022 at 18:21
- Its not an api, the site also has no login system. I have got it to work using the manual validation class and returning the json response manually, however this is not a good approach as it makes the controller look messy. – sgb999 Commented Feb 19, 2022 at 18:42
3 Answers
Reset to default 8If validation fails during a traditional HTTP request, a redirect response to the previous URL will be generated.
If the ining 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."
]
}
If you specify the Accept:application/json
header in request, laravel will return json 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);
}
});