ux icon indicating copy to clipboard operation
ux copied to clipboard

[LiveComponent] Set value on LiveCollectionField

Open BaptisteChabrol opened this issue 1 year ago • 4 comments

Hello, I have a dynamicForm on a Appointment Entity. This entity has a Tracking entity relation (OneToMany).

I use the LiveCollectionField on my AppointmentForm to add dynamically a tracking. I want to set default date on a new tracking with $this->formValues['trackings'][$index] = ['date' => new \DateTime()];

But when I click on the add button, I have this error : Unable to dehydrate value of type "array" for property "formValues" on component "App\Twig\Components\AppointmentForm". Change this to a simpler type of an object that can be dehydrated. Or set the hydrateWith/dehydrateWith options in LiveProp or set "useSerializerForHydration: true" on the LiveProp to use the serializer.

When I try to set useSerializerForHydration like this : #[LiveProp(useSerializerForHydration: true)] public ?Appointment $initialFormData = null;

I have this error (I have 2 relations with the User entity in Tracking, ManyToMany and ManyToOne) : Error rendering "AppointmentForm" component: A circular reference has been detected when serializing the object of class "Proxies\__CG__\App\Entity\User" (configured limit: 1).

BaptisteChabrol avatar Apr 15 '24 09:04 BaptisteChabrol

So you need to help the serializer there :)

You can probably solve this with one of the following solutions:

  • setting a context
  • use custom dehydrate/hydrate method
  • une a custom hydration extension

See https://symfony.com/bundles/ux-live-component/current/index.html#hydrating-with-the-serializer for details

If i were you, i'll try in isolation (outside the livecomponent) to dehydrate your object with the Serializer service, and then bring this configuration in the LiveProp.. it will be much easier to test/debug :)

smnandre avatar Apr 16 '24 18:04 smnandre

formValues supposed to store ~~scalars~~normalized values, so it should be a datetime string instead of an object

norkunas avatar Apr 17 '24 03:04 norkunas

Thanks for your feedback. The problem was with the serialization of my User entity, i needed to use the Groups annotation to normalize all fields of my Appointment entity (without id), all Tracking fields (without id and appointment) and the User id.

So to set default value on my new Tracking with the LiveCollectionField, I do this :

(Form)

    use LiveCollectionTrait {
        addCollectionItem as traitAddCollectionItem;
    }

    ....

    #[LiveAction]
    public function addCollectionItem(PropertyAccessorInterface $propertyAccessor, #[LiveArg] string $name): void
    {
        $this->traitAddCollectionItem($propertyAccessor, $name);

       // to get index of the created Tracking
        $propertyPath = $this->fieldNameToPropertyPath($name, $this->formName);
        $data = $propertyAccessor->getValue($this->formValues, $propertyPath);
        $index = [] !== $data ? max(array_keys($data)) : 0;

        /** @var User $currentUser */
        $currentUser = $this->security->getUser();
        $tracking = (new Tracking())->setDate(new \DateTime());

        $this->formValues['trackings'][$index] = $this->normalizer->normalize($tracking, null, ['groups' => 'tracking']);
        $this->formValues['trackings'][$index]['user'] = $currentUser->getId();
    }

I don't know if this is the best solution but it works. Thanks for your help

BaptisteChabrol avatar Apr 18 '24 06:04 BaptisteChabrol

Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?

carsonbot avatar Oct 19 '24 12:10 carsonbot

Could I get an answer? If I do not hear anything I will assume this issue is resolved or abandoned. Please get back to me <3

carsonbot avatar Nov 02 '24 12:11 carsonbot

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

carsonbot avatar Nov 16 '24 12:11 carsonbot