Skip to content

Form field is set to NULL, even when not neccessary #43

@cklm

Description

@cklm

Thank you very much for this package - it might change how we work with forms forever ;)

Version is current v0.1.3, symfony is at 6.4.

When testing I found a bug: I bound an entity to the DynamicFormBuilder:

// App\Entity\User
class User {

    public const int TYPE_USER = 1;
    public const int TYPE_ADMIN = 2;
    
    protected int $type=self::TYPE_USER;

    public function setType(int $type): static
    {
        $this->type = $type;

        return $this;
    }
}


// App\Form\UserType
class UserType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {

        $builder = new DynamicFormBuilder($builder);
        $builder->add('choice',CheckboxType::class, [
            'label' => 'select type?',
            'required' => false,
            'mapped' => false,
        ]);

        $builder->addDependent('type',['choice'],static function(DependentField $field, ?bool $choice) {
            if($choice===false) {
                return;
            }

            $field->add(ChoiceType::class, [
                'label' => 'Typ',
                'choices' => User::TYPES,
                'constraints' => [],
            ]);
        });
    }
}

When the user now ticks select type? the form rerenders and throws an exception: Expected argument of type "int", "null" given at property path "type".. $form->submit() in ComponentWithFormTrait.php tries to map the (empty) data to the entity and therefore tries to set $type to NULL. Workaround is to allow NULL in setType(), but then to ignore it. Otherwise use a dto for the form and later transfer it to the entity.

Complete stacktrace:

TypeError:
App\Entity\User::setType(): Argument #1 ($type) must be of type int, null given, called in C:\projekte\test-project\vendor\symfony\property-access\PropertyAccessor.php on line 543
at C:\projekte\test-project\src\Entity\User.php:221
at App\Entity\User->setType(null)
(C:\projekte\test-project\vendor\symfony\property-access\PropertyAccessor.php:543)
at Symfony\Component\PropertyAccess\PropertyAccessor->writeProperty(array(object(User)), 'type', null)
(C:\projekte\test-project\vendor\symfony\property-access\PropertyAccessor.php:120)
at Symfony\Component\PropertyAccess\PropertyAccessor->setValue(object(User), object(PropertyPath), null)
(C:\projekte\test-project\vendor\symfony\form\Extension\Core\DataAccessor\PropertyPathAccessor.php:75)
at Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor->setValue(object(User), null, object(Form))
(C:\projekte\test-project\vendor\symfony\form\Extension\Core\DataAccessor\ChainAccessor.php:48)
at Symfony\Component\Form\Extension\Core\DataAccessor\ChainAccessor->setValue(object(User), null, object(Form))
(C:\projekte\test-project\vendor\symfony\form\Extension\Core\DataMapper\DataMapper.php:74)
at Symfony\Component\Form\Extension\Core\DataMapper\DataMapper->mapFormsToData(object(RecursiveIteratorIterator), object(User))
(C:\projekte\test-project\vendor\symfony\form\Form.php:551)
at Symfony\Component\Form\Form->submit(array())
(C:\projekte\test-project\vendor\symfony\ux-live-component\src\ComponentWithFormTrait.php:155)
at App\Twig\Components\UserTest->submitForm(false)
(C:\projekte\test-project\vendor\symfony\ux-live-component\src\ComponentWithFormTrait.php:111)
at App\Twig\Components\UserTest->submitFormOnRender()
(C:\projekte\test-project\vendor\symfony\ux-live-component\src\EventListener\LiveComponentSubscriber.php:328)
at Symfony\UX\LiveComponent\EventListener\LiveComponentSubscriber->createResponse(object(MountedComponent))
(C:\projekte\test-project\vendor\symfony\ux-live-component\src\EventListener\LiveComponentSubscriber.php:258)
at Symfony\UX\LiveComponent\EventListener\LiveComponentSubscriber->onKernelView(object(ViewEvent), 'kernel.view', object(TraceableEventDispatcher))
(C:\projekte\test-project\vendor\symfony\event-dispatcher\Debug\WrappedListener.php:116)
at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(ViewEvent), 'kernel.view', object(TraceableEventDispatcher))
(C:\projekte\test-project\vendor\symfony\event-dispatcher\EventDispatcher.php:220)
at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(WrappedListener), object(WrappedListener)), 'kernel.view', object(ViewEvent))
(C:\projekte\test-project\vendor\symfony\event-dispatcher\EventDispatcher.php:56)
at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(ViewEvent), 'kernel.view')
(C:\projekte\test-project\vendor\symfony\event-dispatcher\Debug\TraceableEventDispatcher.php:139)
at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(object(ViewEvent), 'kernel.view')
(C:\projekte\test-project\vendor\symfony\http-kernel\HttpKernel.php:186)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(C:\projekte\test-project\vendor\symfony\http-kernel\HttpKernel.php:76)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(C:\projekte\test-project\vendor\symfony\http-kernel\Kernel.php:197)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(C:\projekte\test-project\vendor\symfony\runtime\Runner\Symfony\HttpKernelRunner.php:35)
at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
(C:\projekte\test-project\vendor\autoload_runtime.php:29)
at require_once('C:\\projekte\\test-project\\vendor\\autoload_runtime.php')
(C:\projekte\test-project\public\index.php:5)

Am I missing something? Through the setting to NULL the default value of $type is also lost. Adding 'data' => User::TYPE_USER, does not prevent the exception.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions