Reputation: 336
i have a entity called DynamicForm, which looks like this:
<?php
namespace App\Entity\Product\DynamicForm;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;
/**
* Class DynamicForm
* @package App\Entity\Product
*
* @Entity
* @ORM\Table(name="product_dynamic_form")
*/
class DynamicForm
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(name="id", type="integer", unique=true, nullable=false)
*/
private ?int $id = null;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Product\DynamicForm\Component\Text", mappedBy="dynamicForm")
* @ORM\JoinColumn(name="component_text_id", referencedColumnName="id")
*/
private ?Collection $textComponents;
/**
* @return Collection|null
*/
public function getTextComponents(): ?Collection
{
return $this->textComponents;
}
/**
* @param Collection|null $textComponents
*
* @return DynamicForm
*/
public function setTextComponents(?Collection $textComponents): DynamicForm
{
$this->textComponents = $textComponents;
return $this;
}
}
Also i created a related type for it - DynamicFormType:
<?php
namespace App\Type\Product\DynamicForm;
use App\Entity\Product\DynamicForm\DynamicForm;
use App\Type\Product\DynamicForm\Component\TextType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DynamicFormType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('textComponents', CollectionType::class, [
'entry_type' => TextType::class,
'entry_options' => ['label' => false],
'allow_add' => true,
'allow_delete' => true,
'label' => ' '
])
->add('submit', SubmitType::class, [
'label' => 'form.basic.save'
]);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('data_class', DynamicForm::class);
}
}
The TextType entry type class from the namespace App\Type\Product\DynamicForm\Component\TextType looks like this:
<?php
namespace App\Type\Product\DynamicForm\Component;
use App\Entity\Product\DynamicForm\Component\Text;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as FormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;
class TextType extends AbstractType
{
private TranslatorInterface $translator;
/**
* TextType constructor.
*
* @param TranslatorInterface $translator
*/
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('label', FormType\TextType::class, [
'required' => true,
'translation_domain' => 'wedding',
'label' => 'setting.form.dynamic_by_user.query_to_guest'
])
->add('type', FormType\ChoiceType::class, [
'required' => true,
'translation_domain' => 'wedding',
'label' => 'setting.form.dynamic_by_user.select_type',
'attr' => [
'class' => 'enriched',
'data-search-placeholder' => $this->translator->trans('select.search'),
'data-search-no-results-text' => $this->translator->trans('select.search_no_results_found')
],
'choice_translation_domain' => 'wedding',
'choices' => [
'setting.form.dynamic_by_user.type_text' => Text::TYPE_TEXT_FIELD,
'setting.form.dynamic_by_user.type_textarea' => Text::TYPE_TEXT_AREA,
'setting.form.dynamic_by_user.type_email' => Text::TYPE_EMAIL_FIELD,
'setting.form.dynamic_by_user.type_number' => Text::TYPE_NUMBER_FIELD,
]
]);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('data_class', Text::class);
}
}
While i try to transmit the form, the request in the controller contains the form data as you can see it, in the following screenshot:
My problem is now that i always get the following error (while handling the request for the form via ->handleRequest($request) on created form in controller):
Expected argument of type "?Doctrine\Common\Collections\Collection", "array" given at property path "textComponents".
I have such collection settings also in other classes, but without problems - I don't know any further, can anyone please assist me or see the error?
(I am using Symfony version 5.2.9, if u need any further info just ask for it - I will give it to you as soon as possible)
Upvotes: 6
Views: 6861
Reputation: 187
I was able to fix this by doing this, that allows us to pass a Collection or an empty array or an array of your entity which I think is Text:
/**
* @param Collection|Text[] $textComponents
*
* @return DynamicForm
*/
public function setTextComponents($textComponents): DynamicForm
{
$this->textComponents = $textComponents;
return $this;
}
Upvotes: 1
Reputation: 1646
Trying to add a constructor in your entity
public function __construct()
{
$this->textComponents = new ArrayCollection();
}
Add addTextComponent
and removeTextComponent
methods intead of setTextComponents
public function addTextComponent(Text $textComponent): self
{
$textComponent->setDynamicForm($this);
$this->textComponents->add($textComponent);
return $this;
}
public function removeTextComponent(Text $textComponent): self
{
$this->textComponents->removeElement($textComponent);
return $this;
}
Add 'by_reference' => false
in the textComponents form params
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('textComponents', CollectionType::class, [
'entry_type' => TextType::class,
'entry_options' => ['label' => false],
'allow_add' => true,
'allow_delete' => true,
'label' => ' ',
'by_reference' => false,
])
->add('submit', SubmitType::class, [
'label' => 'form.basic.save'
]);
}
Upvotes: 7