2

Form:

$builder->add('positions', CollectionType::class, [
    'entry_type' => FooPositionType::class,
    'allow_add' => true,
    'allow_delete' => true,
    'delete_empty' => true,
    'prototype' => true,
    'prototype_data' => (new FooPosition($foo)),
    'by_reference' => false,
    'disabled' => $disable,
]);

FooPositionType.php:

class FooPositionType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $foo = $builder->getData(); // this is set when displaying the form
                                    // but null during $form->handleRequest();

        $builder
            ->add('text', TextType::class, [
                'required' => false,
            ]);
    }

public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => FooPosition::class,
        ]);
    }
}

FooPosition.php:

#[ORM\Entity]
class FooPosition
{
    #[ORM\Column(type: 'integer')]
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'IDENTITY')]
    public int $id;

    public function __construct(
        #[ORM\ManyToOne(targetEntity: Foo::class, inversedBy: 'positions')]
        private Foo $foo
    ) {}
}

The issue is that when I save a new FooPosition, I get the error message Too few arguments to function App\Entity\FooPosition::__construct(), 0 passed in var/www/svm/vendor/symfony/form/Extension/Core/Type/FormType.php on line 160 and exactly 1 expected

If I change the FooPosition constructor to private ?Foo $foo = null, everything works fine, but I do not wish to make FooPositions constructable without a proper Foo relation. How would I go about fixing this so it works? 'prototype_data' is supposed to handle this, but for some reason it doesn't.

mhpcc
  • 120
  • 1
  • 12
  • Have a look here: https://symfony.com/doc/current/form/dynamic_form_modification.html, especially the FormEvents like FormEvents::POST_SUBMIT – Benjamin Kozlowski Dec 17 '21 at 10:45
  • @BenjaminKozlowski I fail to see how that is related to my question in any way. – mhpcc Dec 17 '21 at 12:24
  • It is related because afaik your problem derives from how symfony/doctrine works in the handleRequest method when it maps the form data to the entity. Symfony doesn't know about your constructor param in your entity. prototype_data isn't supposed to handle this. prototype_data is to add data to the prototype of the form but not what happens when the form is submitted. I think you can do something with the events, at least you have the data there that you're currently missing when the form is submitted. If that doesn't work i'd use DTOs – Benjamin Kozlowski Dec 17 '21 at 14:46
  • I see, I "solved" the issue by passing 'empty_data' => fn () ) => new FooPosition($foo) to 'entry_options'. It just doesn't seem elegant that it has to be specified in two places. – mhpcc Dec 17 '21 at 15:27

0 Answers0