Action Modal closes itself when receiving Validation Errors via setErrorBag

What I am trying to do: Have my action modal with a form not close when validation errors are thrown. What I did:
class InquiryModal extends Component implements HasForms, HasActions
{
use InteractsWithForms;
use InteractsWithActions;

public $data;

public function openInquiryModal(): Action
{
return Action::make('openInquiryModal')
->label('Ask')
->action(function (array $data): void {
try {
app(CreatesInquiry::class)->create($data);
} catch (ValidationException $e) {
$this->setErrorBag($e->errors());
}
})
->form([
TextInput::make('first_name')
->label(__('common.first_name'))
->maxLength(32)
->autocomplete('given-name')
->required(),
Textarea::make('message')
->label($this->textAreaLabel)
->required(),
]);
}

public function render()
{
return view('livewire.inquiry-modal');
}
}

// Validation:
class CreateInquiry implements CreatesInquiry
{
public function create(array $input)
{
Validator::make($input, [
'event_id' => 'required|exists:events,id',
'first_name' => 'required|string|max:32',
'last_name' => 'required|string|max:32',
'email' => 'required|email|max:1',
'phone' => 'nullable|string|max:32',
'message' => 'nullable|string',
])->validateWithBag('createInquiry');

$inquiry = new Inquiry();
$inquiry->fill($input);
$inquiry->save();

return $inquiry;
}
}
class InquiryModal extends Component implements HasForms, HasActions
{
use InteractsWithForms;
use InteractsWithActions;

public $data;

public function openInquiryModal(): Action
{
return Action::make('openInquiryModal')
->label('Ask')
->action(function (array $data): void {
try {
app(CreatesInquiry::class)->create($data);
} catch (ValidationException $e) {
$this->setErrorBag($e->errors());
}
})
->form([
TextInput::make('first_name')
->label(__('common.first_name'))
->maxLength(32)
->autocomplete('given-name')
->required(),
Textarea::make('message')
->label($this->textAreaLabel)
->required(),
]);
}

public function render()
{
return view('livewire.inquiry-modal');
}
}

// Validation:
class CreateInquiry implements CreatesInquiry
{
public function create(array $input)
{
Validator::make($input, [
'event_id' => 'required|exists:events,id',
'first_name' => 'required|string|max:32',
'last_name' => 'required|string|max:32',
'email' => 'required|email|max:1',
'phone' => 'nullable|string|max:32',
'message' => 'nullable|string',
])->validateWithBag('createInquiry');

$inquiry = new Inquiry();
$inquiry->fill($input);
$inquiry->save();

return $inquiry;
}
}
My issue/the error: The issue is that the modal closes. I can see that the browser receives an "close-modal" when I click submit in the modal. Thus the user can't see the errors.
2 Replies
toeknee
toeknee2w ago
I suspect it's the mapped keys because it's a view modal I do have the same issue with a table in a modal, will try to resfult
warhost.
warhost.OP2w ago
Ah, it closes because the exception is caught, if it's not caught it stays open. However it still doesn't show the errors under the respective fields 😦
->action(function (array $data): void {
try {
app(CreatesInquiry::class)->create($data);
} catch (ValidationException $e) {
$this->setErrorBag($e->errors());

throw $e;
}
})
->action(function (array $data): void {
try {
app(CreatesInquiry::class)->create($data);
} catch (ValidationException $e) {
$this->setErrorBag($e->errors());

throw $e;
}
})
You are right. It doesn't show the errors because the wire keys are very different to what's used in the validator:
wire:model="mountedActionsData.0.email"
wire:model="mountedActionsData.0.email"

Did you find this page helpful?