'Laravel FormRequest failed validation returns 302 redirect instead of 422 with errors
I have modalform on website. Full backend and frontend code is below. I cannot understand how validation works. When I put more than 20 symbols in name field I don't see any errors in Laravel debugbar, no info in Session tab in Laravel Debugbar. I just can see in Chrome Devtools under network tab some info about it:
- On the screenshot below you can see that first modalform request has status 200. This happens when I put name between 3 and 20 symbols. And finally I receive email in my mailbox.
- And second modalform request has status 302. But I don't see any error on webpage, no errors in Laravel debugbar, no info in Session tab in Laravel Debugbar.
Can somebody explain me how it works and what is wrong with my code? Without seeing validation errors it is very hard to find the problem.
I have modalform on website. routes\web.php
Route::post('/modalform', 'MainController@modalform')->name('modalform');
app\Http\Controllers\MainController.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\Modalform;
use App\Http\Requests\ModalformRequest;
class MainController extends Controller
{
public function modalform(ModalformRequest $request) {
Mail::to( config('mail.to.address') )->send(new Modalform());
return response()->json([
'status' => 'success',
'messageHeader' => 'Your message sent!',
'messageContent' => 'We will contact you soon.'
]);
}
app\Http\Requests\ModalformRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ModalformRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'string|between:3,20|required',
];
}
}
app\Mail\Modalform.php
use Illuminate\Http\Request;
use App\Http\Requests\ModalformRequest;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class Modalform extends Mailable
{
use Queueable, SerializesModels;
public $subject = 'request from Modalform';
public function build(ModalformRequest $request)
{
$this->from( config('mail.from.address') )
->view('emails.modalform')
->withRequest($request);
}
}
views\emails\modalform.blade.php
<p><strong>{{ $request->name }}</strong></p>
<p><strong>{{ $request->phone }}</strong></p>
<p><strong>{{ $request->email }}</strong></p>
<p><strong>{{ $request->address }}</strong></p>
<p>{{ $request->message }}</p>
<p> Message sent from <a href="{{ $request->headers->get('referer') }}">{{ $request->headers->get('referer') }}</a></p>
views\partials\modalform.blade.php
<style>
[x-cloak] {
display: none;
}
</style>
<div class="topbar bg-white border-b border-gray-100"
x-data="topbar()"
x-cloak
>
<div class="flex justify-between items-center flex-wrap text-xs p-0 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="cursor-pointer">
<div class="relative" @click="openModal = !openModal">
<svg class="h-6 w-6 fill-current">
<use xlink:href="envelope-outline"></use>
</svg>
</div>
</div>
</div>
<!-- Modal -->
<div x-show="openModal" class="fixed z-50 inset-0 overflow-y-auto"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-50"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-50"
x-cloak
>
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
-->
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
</div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
<!--
Modal panel, show/hide based on modal state.
-->
<div @click.away="openModal = false" class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full" role="dialog" aria-modal="true" aria-labelledby="modal-headline">
<form method="POST" action="/modalform" method="POST" @submit.prevent="submitData()">
@csrf
<div class="bg-white">
<div class="modalbuttons flex place-items-center text-center border-b cursor-pointer text-lg leading-6 font-medium text-gray-900">
<h3 class="p-2 hover:bg-gray-100 hover:text-blue-500"
@click="callback = true, zamer = false, eskiz = false"
:class="callback ? 'bg-gray-100 text-blue-500' : ''"
>
Callback request
</h3>
<h3 class="p-2 hover:bg-gray-100 hover:text-blue-500"
@click="callback = false, zamer = true, eskiz = false"
:class="zamer ? 'bg-gray-100 text-blue-500' : ''"
>
Signup for a measurement
</h3>
<h3 class="p-2 hover:bg-gray-100 hover:text-blue-500"
@click="callback = false, zamer = false, eskiz = true"
:class="eskiz ? 'bg-gray-100 text-blue-500' : ''"
>
Send sketch for quuotation
</h3>
<div class="p-2 place-self-stretch hover:bg-gray-100 hover:text-blue-500" @click="openModal = false" >
<span class="text-3xl">×</span>
</div>
</div>
<div class="flex items-start flex-wrap p-5"
x-show="!sent"
>
<div class="text-left w-full">
<div class="mt-2 grid grid-cols-2 gap-x-4 gap-y-2">
<!-- Name -->
<div class="name">
<label class="block font-medium text-sm text-gray-700" for="name"> Name </label>
<div class="relative text-gray-400 focus-within:text-gray-800">
<input id="name" type="text" name="name" x-model="formData.name" placeholder="Fill in the name" autofocus="autofocus" data-cip-id="name">
</div>
</div>
<!-- Phone -->
<div class="phone">
<label class="block font-medium text-sm text-gray-700" for="phone"> Phone </label>
<div class="relative text-gray-400 focus-within:text-gray-800">
<input id="phone" type="text" name="phone" x-model="formData.phone" placeholder="Fill in the phone" autofocus="autofocus" data-cip-id="phone">
</div>
</div>
<!-- Email Address -->
<div class="email" x-show="zamer || eskiz" >
<label class="block font-medium text-sm text-gray-700" for="email"> Email </label>
<div class="relative text-gray-400 focus-within:text-gray-800">
<input id="email" type="text" name="email" x-model="formData.email" placeholder="Fill in the email" autofocus="autofocus" data-cip-id="email">
</div>
</div>
<!-- Address -->
<div class="address" x-show="zamer || eskiz">
<label class="block font-medium text-sm text-gray-700" for="address"> Address </label>
<div class="relative text-gray-400 focus-within:text-gray-800">
<input id="address" type="text" name="address" x-model="formData.address" placeholder="Fill in the address" autofocus="autofocus" data-cip-id="address">
</div>
</div>
</div>
<!-- Message -->
<div class="message">
<label class="block font-medium text-sm text-gray-700" for="message"> Message </label>
<div class="relative text-gray-400 focus-within:text-gray-800">
<input id="message" type="text" name="message" x-model="formData.message" placeholder="Fill in the message" autofocus="autofocus" data-cip-id="message">
</div>
</div>
<p x-text="message" class="text-green-600"></p>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 flex justify-between ">
<button type="submit" @click.prevent="openModal = false"><span>Cancel</span></button>
<button type="submit" x-text="buttonLabel" @click.prevent="submitData()">Send</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- /Modal -->
</div>
<script>
function topbar() {
return {
mailTooltip: false,
instagramTooltip: false,
openModal: false,
callback: true,
zamer: false,
eskiz: false,
formData: {
name: '',
phone: '',
email: '',
address: '',
message: '',
_token: '{{ csrf_token() }}'
},
message: '',
loading: false,
sent: false,
buttonLabel: 'Send',
resetFields() {
this.formData.name = '',
this.formData.phone = '',
this.formData.email = '',
this.formData.address = '',
this.formData.message = ''
},
submitData() {
this.buttonLabel = 'Sending...';
this.loading = true;
this.message = '';
fetch('/modalform', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(this.formData)
})
.then(() => {
this.resetFields(),
this.message = 'Message sent successfully!',
this.sent = true
})
.catch(() => {
this.message = 'Ooops! Something went wrong!'
})
.finally(() => {
this.loading = false;
this.openModal = false;
this.buttonLabel = 'Send';
this.message = '';
this.sent = false
})
},
}
}
</script>
then in the main teplate I have this
@if (session('status'))
<!-- Session message -->
<session>
<x-modules.alert style="{{ session('status') }}">
<x-slot name="messageHeader">{{ session('messageHeader') }}</x-slot>
<x-slot name="messageContent">{{ session('messageContent') }}</x-slot>
</x-modules.alert>
</session>
@endif
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|

