Home > OS >  Entity of type passed to the choice field must be managed. Maybe you forget to persist it in the ent
Entity of type passed to the choice field must be managed. Maybe you forget to persist it in the ent

Time:09-23

I made a search form where several entities are present. I would like to keep last values entered so that when user comes back to the form, he retrieves his last choices.

By trying to do so, I retrieve myself with the following error :

Entity of type "App\Entity\BigCity" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?

When I saw this error, I added the following line : $entityManagerInterface->persist($data); but I retrieve myself with an other error :

EntityManager#persist() expects parameter 1 to be an entity object, array given.

What should I do to avoid these errors ?

EventsController.php

<?php

namespace App\Controller;

use App\Form\SearchType;
use App\Repository\EventsRepository;
use App\Repository\CategoriesRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class EventsController extends AbstractController
{   
    private $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    #[Route('/search', name: 'search')]
    public function search(Request $request, EntityManagerInterface $entityManagerInterface,)
    {   
        $data = $request->query->all();
        $sessionFormData  = $sessionInterface->get('data');

        $form = $this->createForm(SearchType::class, $sessionFormData);
        $form->handleRequest($request);
        
        if ($form->isSubmitted() && $form->isValid()) {
            $data = $form->getData();
            $session->set('data', $data);
            return $this->render('front/events.html.twig', $data);
        }

        return $this->renderForm('front/search.html.twig', [
            'form' => $form
        ]);
    }

SearchType.php

<?php

namespace App\Form;

use App\Entity\BigCity;
use App\Entity\Categories;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class SearchType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('bigcity', EntityType::class, [
                'class' => BigCity::class,
                'choice_label' => 'name',
                'placeholder' => 'Sélectionne une grande ville'
            ])
            ->add('category', EntityType::class, [
                'class' => Categories::class,
                'choice_label' => 'image',
                'expanded' => true,
                'multiple' => false,
            ])
            ->add('save', SubmitType::class)
        ;
    }

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

CodePudding user response:

if you want to save values in session you can use SessionInterface, after that you pass the sessions values in the options of createForm method

use Symfony\Component\HttpFoundation\Session\SessionInterface;

public function someAction(Request $request, SessionInterface $session)
{
   $data = $request->request->all();

   $sessionSearchFormData  = $session->get('searchFormData'); // null at the first time

   $form = $this->createForm(SearchType::class, null, ['sessionSearchFormData'=> $sessionSearchFormData]);
   $form->handleRequest($request);

    if($form->isSubmitted())
    {
        // put values of form in session just after each time the form is submitted
        $session->set('searchFormData', $data);
    }

}

use Doctrine\ORM\EntityManagerInterface;

class SearchType extends AbstractType
{
   private EntityManagerInterface $entityManager;

   public function __construct(EntityManagerInterface $entityManager)
   {
      $this->entityManager = $entityManager;
   }

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

    $bigcity = $options['sessionSearchFormData'] !== null ? $options['sessionSearchFormData']['bigcity'] : '';

    $builder
        ->add('bigcity', EntityType::class, [
            'class' => BigCity::class,
            'choice_label' => 'name',
            'placeholder' => 'Sélectionne une grande ville',
            'data'=> $bigcity !== null ? $this->entityManager->getRepository(BigCity::class)->find($bigcity) : ''
        ])
        ->add('category', EntityType::class, [
            'class' => Categories::class,
            'choice_label' => 'image',
            'expanded' => true,
            'multiple' => false,
        ])
        ->add('save', SubmitType::class)
    ;
}

public function configureOptions(OptionsResolver $resolver): void
{
    $resolver->setDefaults([
        'data_class' => null,
         'sessionSearchFormData' => null, // don't forget this
    ]);
}

EDIT:

This is another solution, you don't need to do anything in the formType nor passing any values as options, just remove $form->handleRequest and add $form->submit()

In twig

<form action="" method="post">

The controller

public function someAction(Request $request, SessionInterface $session)
{
    // $data = $request->query->all(); // if GET method
    $data = $request->request->all(); // if POST method
    
    if($request->getMethod() === 'POST') {
        $session->set('searchFormData', $data);
    }
    $sessionSearchFormData = $session->get('searchFormData');

    $form = $this->createForm(SearchType::class);
    $form->submit($sessionSearchFormData);

    return $this->renderForm('front/search.html.twig', [
        'form' => $form
    ]);
}
  • Related