Search code examples
phpsymfonydependency-injectionformbuilder

cannot load the TranslatorInterface in my formType


I try to introduce some translation into a ChatBundle in order to follow the changes of the _locale of the hosting app in Symfony 4.

So in the formBuilder i try to inject the TranslatorInterface as such:

// lib/ChatBundle/Form/ChatMessageType.php

namespace bornToBeAlive\ChatBundle\Form;

use bornToBeAlive\ChatBundle\Entity\ChatMessage;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Translation\TranslatorInterface;

class ChatMessageType extends AbstractType
{
    private $trans;

    public function __construct(TranslatorInterface $trans)
    {
        $this->trans = $trans;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('content', null, [
                'attr'=> ['placeholder' => $this->trans->trans('placeholder',[],'chat')]
            ])
        ;
    }

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

but when I try to run my show action:

public function show(): Response
{
    $message = new ChatMessage();

    $form = $this->createForm(ChatMessageType::class, $message);

    return $this->render('@Chat/show.html.twig', [
        'form' => $form->createView(),
    ]);
}

I get the following error :

Too few arguments to function bornToBeAlive\ChatBundle\Form\ChatMessageType::__construct(), 0 passed in ../vendor/symfony/form/FormRegistry.php on line 92 and exactly 1 expected

I'm surprised because I use this technique when I'm in my host app for the other type. did I do something wrong ?


Solution

  • According to the Symfony 4.4 Form documentation :

    If you're using the default services.yaml configuration, this example will already work! Otherwise, create a service for this form class and tag it with form.type.

    services:
        # default configuration for services in *this* file
        _defaults:
            autowire: true      
            autoconfigure: true 
            public: false 
    

    If autowiring is not working as expected, you can define form as service, like this

    # config/services.yaml
    app.form.corporation_type:
        class: bornToBeAlive\ChatBundle\Entity\ChatMessageType
        arguments: ["@translator"]
        tags:
            - { name: form.type }