[LiveComponent] Validation doesn't seem to work
Hi team!
I'm trying to validate a property of some LiveComponent that doesn't use a Symfony Form. I'm following this: https://symfony.com/bundles/ux-live-component/current/index.html#validation-without-a-form
My code is like this:
#[AsLiveComponent]
class MyComponent
{
use DefaultActionTrait;
use ValidatableComponentTrait;
#[LiveProp(writable: true)]
#[Assert\Choice(choices: ['foo', 'bar'])]
public string $type;
// ...
}
If I put this in my template, I expect to see an error, but I don't see anything. The LiveComponent renders normally, without validating the value of the $type property:
<twig:MyComponent type="aaaaa"/>
Also, on the Symfony Docs, I don't understand the followin:
Be sure to add the IsValid attribute/annotation to any property
where you want the object on that property to also be validated.
The docs doesn't show any example using that IsValid attribute and I'm not sure where to find it. Thanks!
I think that sentence is a mistake in the documentation.
Be sure to add the
IsValidattribute/annotation to any property where you want the object on that property to also be validated.
I think it's a typo and should be Valid instead of Isvalid.
You can see the example with #[Assert\Valid] added to the $user property.
We add the Valid constraint when we want to check validation constraints of the related object (the User object in the example).
But the Valid constraint is only used to validate objects, so it's probably not related to your issue.
Hi, yes there is a typo on IsValid attribute, it should be Valid insteadd but it will only works for object.
About your validation error, the method $this->validate() is responsible for validating your props. It is automatically called in validateAfterHydration during PostHydrate hook, but that only works when the component state has been is loaded from the client (i.e.: after triggering a LiveAction).
To validate your component props at initial render, you must call $this->validate(throw: false) by yourself, during a PostMount hook, example:
<?php
namespace App\Twig\Components;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\DefaultActionTrait;
use Symfony\UX\LiveComponent\ValidatableComponentTrait;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\UX\TwigComponent\Attribute\PostMount;
#[AsLiveComponent]
final class ComponentWithValidation
{
use DefaultActionTrait;
use ValidatableComponentTrait;
#[LiveProp(writable: true)]
#[Assert\Choice(choices: ['foo', 'bar'])]
public string $type;
#[PostMount]
public function initialValidation(): void
{
$this->validate(false);
}
}
With this modification on your component, I'm able to see the validation errors at initial rendering
The documentation could be fixed, improved, and tests aswell
Thanks for the detailed answer. I'm going to play with this a bit and I'll propose some doc tweaks after that.
The only thing I don't like much is this: $this->validate(false); It totally looks like "DON'T validate this" but it's the opposite.
Yeah, that's like Response::getHeaders() from HttpClient, but using named arguments helps a lot :)