Why symfony assert doesnt work with novalidation attribute on Edit Page?

1.3k views Asked by At

On my form, I am using novalidate attribute like this :

{{ form_start(form, {'attr': {novalidate: 'novalidate'}}) }}                

To disable HTML5 browser validation. So Symfony assert errors appears. On the new.html.twig page it works perfectly fine! The novalidate attribute disable the html5 validation and the assert errors appear.

But when I use the novalidate attribute on edit.html.twig and leave the username field empty (i don't fill it on the form) the @Assert\NotBlank() doesn't work. And I get this error

Expected argument of type "string", "null" given at property path "username".

Why symfony assert work on the new page, but it doesnt work on the edit page? By the way, i am not using any validation groups.

here is the code of my User entity(without getters and setters) :

class User implements UserInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Email()
     * @Assert\NotBlank()
     */
    private $email;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank()
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank()
     * @Assert\Length(
     *      min = 8, max = 30,
     *      minMessage = "Your password must be between 6 and 30 characters.")     
     */
    private $password;
    
    /**
     * @ORM\Column(type="json", nullable=true )
     */
    private $roles = [];

Here is the code of the form :

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email', EmailType::class )
            ->add('username', TextType::class)
            ->add('password',PasswordType::class)
        ;
    }

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

both of new.html.twig and edit.html.twig have the same code :

{{ form_start(form, {'attr': {novalidate: 'novalidate'}}) }}    

    {{ form_widget(form.email, {'attr': {'class': 'form-control',placeholder: 'Email Adress'} }) }}     
    {{form_errors(form.email)}}

    {{ form_widget(form.username, {'attr': {'class': 'form-control',placeholder: 'Username'} }) }}
    {{form_errors(form.username)}}

    {{ form_widget(form.password, {'attr': {'class': 'form-control'} }) }}
    {{form_errors(form.password)}}

    <button class="btn btn-success">Submit</button>
{{ form_rest(form) }}
{{ form_end(form) }}

Controller code :

/**
 * @Route("/new", name="user_new", methods={"GET","POST"})
 */
public function new(Request $request): Response
{
    $user = new User();
    $form = $this->createForm(UserType::class, $user);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($user);
        $entityManager->flush();

        return $this->redirectToRoute('user_index');
    }

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


/**
 * @Route("/{id}/edit", name="user_edit", methods={"GET","POST"})
 */
public function edit(Request $request, User $user): Response
{
    $form = $this->createForm(UserType::class, $user);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $this->getDoctrine()->getManager()->flush();

        return $this->redirectToRoute('user_index');
    }

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

my getters and setters :

public function getEmail(): ?string
{
    return $this->email;
}

public function setEmail(string $email): self
{
    $this->email = $email;

    return $this;
}
public function getUsername(): ?string
{
    return $this->username;
}

public function setUsername(string $username): self
{
    $this->username = $username;

    return $this;
}


public function getPassword(): ?string
{
    return $this->password;
}

public function setPassword(string $password): self
{
    $this->password = $password;

    return $this;
}
1

There are 1 answers

0
Dhia Djobbi On BEST ANSWER

I think you should add ? sign to the string type on your all setters.

For example change it From setUsername(string $username): self To setUsername(?string $username): self

This should fix the assert problem on the edit page.