-
-
Notifications
You must be signed in to change notification settings - Fork 368
Description
Let me preface by saying "yea I know this aint probably the right place to ask", but I am fairly certain this problem is unwanted behaviour...but I'd be glad to be proven wrong.
The LiveComponent would be pretty simple:
#[AsLiveComponent(template: 'some_template.html.twig')]
class SomeLiveComponent extends AbstractController
{
use DefaultActionTrait, ComponentWithFormTrait;
protected function instantiateForm(): FormInterface
{
return $this-createForm(SomeFormType::class);
}
#[LiveAction]
public function save(): ?Response
{
try {
/// ... do some persistence
} catch (\Throwable $e) {
$error = new FormError('An error occurred');
$this->form->addError($error); // <--- How would I display this error in my template?
}
}
The template, as simple as can be:
{# some_template.html.twig #}
{{ form_start(form,
{
'attr': {
'data-action': 'live#action:prevent',
'data-live-action-param': 'save'
}
})
}}
{{ form_errors(form) }} <!-- The Error should be displayed here -->
{{ form_row(form.someField) }}
<button type="submit" data-loading="action(save)|addAttribute(disabled)">Submit</button>
{{ form_end(form) }}
A somewhat ugly workaround would be adding a $formErrors array property to the component and populating it with whatever error-messages occur. You could then simply display all those messages in the template, though due to how detached that is from the normal symfony form workflow I would rather avoid this.
I understand that throwing a UnprocessableEntityHttpException() makes turbo re-render the HTML it receives in the response, so the "save()" function should throw that whenever it fails. But the errors are not added to the response HTML anyway - either because the HTML has already been rendered or the FormErrors are removed manually...though I have no idea
I tried adding a writable LiveProp array property to my component which would be populated with FormErrors throughout the submit process - similar to the hacky $formErrors array property mentioned above. But the "instantiateForm()" function would add these errors manually to the form - but that does not work either.
Any pointers would be helpful.
Activity
WebMamba commentedon Jul 13, 2024
Sorry I don't get what you are trying to do here... What error are you trying to catch ? Form errors happen when the value submitted by the user are not valid but no errors are throw the errors are just added to the form. If the error came from outside the form it's a good idea to have an another props for the error outside the form.
Mauriceu commentedon Jul 13, 2024
The Idea is that apart from FormErrors being added by Constraints, FormErrors would also be added manually by the Component.
For example, a User submits some data and this data - if valid from a constraint perspective - is then sent to a third party which validates it against some internal constraints and saves it. If this third party rejects the data, or an error occurs in transit, or while saving it, I would like the Form to reflect that by manually adding a FormError.
To expand on the example above:
If this is currently not possible is it worth thinking about opening a feature request? Otherwise, the FormInterface::addError() function would be obsolete within LiveComponents.
WebMamba commentedon Jul 14, 2024
Ok now I got it now, thanks! You can't add Errors after your form have been submitted and validated. This not about LiveComponent, but more about how Symfony form works. So I think you have two options:
Mauriceu commentedon Jul 15, 2024
Yea I thought about these too, however they would still feel like a workaround, because even when adding the FormError to the form within the "instantiateForm()" function it is not rendered - and at this point the form is not submitted.
smnandre commentedon Jul 17, 2024
Only errors related to validated field / models are kept (see: https://github.com/symfony/ux-live-component/blob/2.x/src/ComponentWithFormTrait.php), and the live props are the form values, not the form itself.
Not sure at all, but maybe you can call resetForm and then add some error ?
palgalik commentedon Dec 11, 2024
I’m struggling with the same issue.
@smnandre
If you were to call the resetForm function, it would clear the already entered input data, which isn’t an option in my case.
@WebMamba
Perhaps you’re not entirely right about this, let me show it.
Here’s a very simple example that shows how to add errors to an input field even after Form validation, beyond the constraints already defined on the field.
TestController.php
test.html.twig
It’s clear that the name field has no validation applied; instead, a FormError is manually added to the field, and the error message appears below the input field.
smnandre commentedon Dec 16, 2024
So you probably need to do something a bit dirthy with https://github.com/symfony/ux-live-component/blob/2.x/src/ValidatableComponentTrait.php
Mauriceu commentedon Feb 24, 2025
@smnandre The ValidatableComponentTrait looks like it can only be used for validating constraints on demand which is nice to have, however the errors I would like to display are somewhat independent of the underlying model and its constraints. While that may sound like a case of "well then display the errors independently of the form", they still kind of belong within the form context and being able to utilize the
form_errors(form)
twig function would prevent implementation of redundant code.Maybe this example showcases the problem a bit better:
Is there a reason why only FormErrors corresponding to a validatedField entry are displayed? Is it possible to make the validatedFields be co-dependent on existing FormErrors on Form instantiation/rendering?
smnandre commentedon Feb 24, 2025
This is why i suggested some diving deep in the Trait if you want to make it work as you wish ... and maybe why not open a PR afterward ?
Mauriceu commentedon Feb 25, 2025
Behold! My first pull request ...
#2602
dubbs commentedon May 1, 2025
I managed to achieve the same effect by nulling out the formView before throwing an exception:
I don't know if this would have any unintended side effects though.
I tested on a basic form, form state is maintained and the errors show up.
Mauriceu commentedon May 9, 2025
@dubbs looks like a valid workaround. Weirdly enough,
$this->submitForm()
must be called beforehand, otherwise the Error will not be rendered.Thanks man, that really helps me out