Search code examples
symfonysymfony-formssymfony6

Why do I get the error: "Expected argument of type "string", "null" given at property path "name" "?


I'm doing a simple update of a record with Doctrine ORM in Symfony 6.4. I do this registry update with an entity called Category, which looks like (Some things are in spanish):

namespace App\Entity;
use App\Repository\CategoriaRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\NotNull;

#[ORM\Entity(repositoryClass: CategoriaRepository::class)]
class Categoria
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;
    #[ORM\Column(length: 100), Assert\NotBlank(message: '¡El nombre es requerido!')]
    private ?string $nombre = null;

    #[ORM\Column(length: 100), Assert\NotBlank(message: '¡El slug es requerido!')]
    private ?string $slug = null;
#Setters and getters...

My controller and specifically the method and route for such an event is like:

    #[Route('/doctrine/categorias/editar/{id}', name: 'doctrine_categorias_editar')]
    public function categoriasEditar(int $id, Request $request, ValidatorInterface $validator, SluggerInterface $slugger): Response
    {
        $categoria = $this->em->getRepository(Categoria::class)->find($id);

        if (!$categoria) {
            throw $this->createNotFoundException('La categoría no existe.');
        }

        $form = $this->createForm(CategoriaFormType::class, $categoria);
        $form->handleRequest($request);

        var_dump($form->getData());

        if ($form->isSubmitted() && $form->isValid()) {
            var_dump($form->getData());
            // $this->em->flush();
            // return $this->redirectToRoute('categoria_inicio');
        } else {
            //throw $this->createAccessDeniedException("Valores erroneos!");
        }

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

The form is like:

class CategoriaFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
#I use ['required' => false] for test errors
            ->add('nombre', TextType::class, ['required' => false])
            ->add('slug', TextType::class, ['required' => false])
            ->add('enviar', SubmitType::class)
        ;
    }

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

The problem is that when I click the "enviar" button, leaving the "nombre" field empty, I would expect the Asserts to do their job and redirect me or something. But I immediately get the error: Expected argument of type "string", "null" given at property path "name". Now, traditionally I also tried:

                $errors = $validator->validate($categoria);

                if (count($errors) > 0) {
                    return $this->render('doctrine/categorias_editar.html.twig', ['form' => $form, 'errors' => $errors]);
                } else {

                    $campos = $form->getData();
    
                    $categoria->setNombre($campos->getNombre());
                    $categoria->setSlug($campos->getSlug());
    
                    //$this->em->persist($categoria);
    
                    $this->em->flush();
                    
                    return $this->redirectToRoute('doctrine_inicio');
                }

Where do I ask, if I had errors. In the same way, I would expect it to get here and just that, it would tell me that there are errors, but nothing, it just skips the message already mentioned.

Another curiosity is in the "IF" "if ($form->isSubmitted() && $form->isValid())" from the controller, If I put a var_dump() or a die('') ​​before, it executes it correctly, if it is inside the if, it never goes through there. only the error occurs.

What is happening? What am I doing wrong?

I have tried both ways to catch the errors, using the "isValid()" and getting errors with: "$errors = $validator->validate($categoria);", if there are errors (count($errors) > 0) and even then it goes to the error and NEVER executes var_dumps or die() inside the "

if ($form->isSubmitted() && $form->isValid()) {
```"

Solution

  • This is funny! I only have to add a "?" in my Entity at the setter method!. Like this:

    public function setNombre(?string $nombre): static
    {
        $this->nombre = $nombre;
    
        return $this;
    }
    public function setSlug(?string $slug): static
    {
        $this->slug = $slug;
    
        return $this;
    }
    

    Now validators works!. Still, thanks everyone for looking at my question! But I still don't understand why it still doesn't execute a var_dump or a die() inside the if with isSubmitted()