SymfonyCasts / dynamic-forms

Add dynamic/dependent fields to Symfony forms
https://symfonycasts.com
MIT License
91 stars 7 forks source link

Entity reference lost during submit cause unwanted insertion instead of update #34

Open fGuix opened 1 week ago

fGuix commented 1 week ago

Hello, I'm using the dependent form fields in a project and I noticed I guess a bug.

In my form type, I have this code:

$builder
...
  ->addDependent('shippingAddress', 'shippingSameAsBillingAddress', function (DependentField $field, ?bool $billingSameAsShippingAddress) use ($options) {
      if (false === $billingSameAsShippingAddress) {
          $field->add(UserAddressType::class, [
              'mapped' => false,
              ...
          ]
          );
      }
  });

Notice this is an unmapped field. During the POST_SET_DATA event, I populate the field with setData() and an entity of class UserAddress. Everything works well.

The problem comes with the submit operation. Doctrine tries to insert a new entity instead of updating the existing. A. I checked the state of my form data, and in the form PRE_SUBMIT event, the id is still here:

image

Then I checked in the form SUBMIT event, and the id is lost at this point:

image

Thus, it tries to create a new userAdress.

B. I tried replacing the dependent field with a classic one, and it works as expected (updating the entity instead of trying to create a new one).

C. might be related to this issue as I didn't get the problem when creating a new one. Only when editing an existing.

fGuix commented 1 week ago

Trying to pinpoint the problem further. I noticed the modelData (that I change in the POST_SET_DATA form event) is reset to null (the initial value) when the dependable field is submitted. (by dependable field I mean shippingSameAsBillingAddress in my example).

image

The new field added does not take into account the data set in POST_SET_DATA. Is this something that should be taken into account ? Any idea of a workaround ? (setting data for those unmapped field when creating the form instead of using event ? a bit annoying as I use the form type sometimes embedded within another type that is class related).

fGuix commented 1 week ago

Also, when checking the option shippingSameAsBillingAddress that make the field userAddress disappear and reappear, the data is empty. So the POST_SET_DATA event is called an unique time at the first form load.

fGuix commented 1 week ago

Maybe found a workaround using Data mapper to set data, and still using POST_SUBMIT event to deal with the data processing. (The fields are now mapped to work with the data mapper)