I am trying to set the choices for a form select dynamically since the choices come from a service call. However, when the form renders in the view, the choices are not there.
I'm doing the following in the FormType
<?php
namespace My\Form\Customer;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ItemReturnRequestForm extends AbstractType
{
/**
* @var EventSubscriberInterface
*/
protected $reasonsSubscriber;
/**
* Returns the name of this type.
*
* @return string The name of this type
*/
public function getName()
{
return 'item_return_request';
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('reason', 'choice', [
'label' => 'order.returns.reason_for_return',
'required' => true,
'multiple' => false,
'expanded' => false,
'placeholder' => 'order.returns.reasons.empty',
'empty_data' => null,
]);
$builder->addEventSubscriber($this->reasonsSubscriber);
}
/**
* @param EventSubscriberInterface $reasonsSubscriber
*/
public function setReasonsSubscriber(EventSubscriberInterface $reasonsSubscriber)
{
$this->reasonsSubscriber = $reasonsSubscriber;
}
}
The FormType
has a service definition which injects the EventSubscriber
instance since that is also a service definition with it's own dependencies.
The EventSubscrbier
looks like
<?php
namespace My\Form\EventSubscriber;
use My\Customer\ItemReturnAware;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
class ReturnReasonEventSubscriber implements EventSubscriberInterface
{
use ItemReturnAware;
public static function getSubscribedEvents()
{
return [
FormEvents::PRE_SET_DATA => 'getReturnReasons',
];
}
public function getReturnReasons(FormEvent $event)
{
$form = $event->getForm();
if ($form->has('reason')) {
$options = $form->get('reason')->getConfig()->getOptions();
$options['choices'] = $this->itemReturnService->getReasons();
$form->add('reason', 'choice', $options);
}
}
}
Everything seems to work fine up until this point. Using XDEBUG I can see that the EventSubscriber
is being triggered. The service call sets $option['choices']
to the expected array value & the field is added successfully.
However, when the form gets rendered. it's as if the EventSubscriber
had never been called.
If it makes a difference, the options array is an un-ordered numeric list.
i.e.
$options = [
10 => 'First choice',
15 => 'Second choice',
20 => 'Third choice',
];
Any ideas?