AymDev
AymDev

Reputation: 7554

Symfony DateType cannot handle null value despite NotBlank constraint

I am making a form with a birthdate field which must be filled:

    ->add('birthdate', DateType::class, [
        'widget' => 'single_text',
        'constraints' => [
            new NotBlank(['message' => 'The birthdate is missing']),
            new LessThanOrEqual([
                'value' => (new \DateTime('now'))->modify('-15 years'),
                'message' => 'Must be 15 or older.',
            ])
        ]
    ])

The form is mapped to a Preregistration Entity which birthdate property must not be null:

    /**
     * @ORM\Column(type="date")
     */
    private $birthdate;

I am "testing" the form and its constraints by adding a novalidate HTML attribute to the empty form, to see how the back-end verifications would act. Despite the NotBlank constraint, I keep getting this error:

InvalidArgumentException:
Expected argument of type "DateTimeInterface", "NULL" given at property path "birthdate".


The exception disappears when I remove the widget key from the birthdate field options (but I need/want to use this widget).

What could cause the constraints to be "bypassed" ?

Upvotes: 0

Views: 2807

Answers (3)

jyotipawar
jyotipawar

Reputation: 1

I tried lots of solution but these not worked for me. I changed setter function of birthdate as mentioned in this link and it worked for me.

Explanation given in above link is-

In this case, the problem was caused by PHP type hinting. If you use type hinting (for instance setBirthDate(\DateTime $value)) then PHP forces you that you actually provide a DateTime object. Obviously, null is not such an object. To resolve this problem, it is possible to give $value a default value like this: setBirthDate(\DateTime $value = null).

This is documented behavior and explained in the PHP Documentation (http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration).

My setter function is like-

public function setBirthdate(\DateTimeInterface $birthdate = null ): self
{
    $this->birthdate = $birthdate;

    return $this;
}

Upvotes: 0

Giovani
Giovani

Reputation: 2547

On your entity setter, allow it to be null

public function setBirthdate(?\DateTimeInterface $birthdate): self
{
    $this->birthdate = $birthdate;

    return $this;
}

Then use assert to validate it

    /**
     * @var DateTime $birthdate
     *
     * @ORM\Column(type="datetime")
     * @Assert\NotNull()
     */
    private $birthdate;

Upvotes: 2

Ali Mhanna
Ali Mhanna

Reputation: 209

i will try the following by removing the constaints from the form type and add it inside the entity.

and this is an example how i am using the forms with no validate tag

form type:

->add(
            'birthdate',
            DateTimeType::class,
            [
                'label' => 'birthdate',
                'widget' => 'single_text',
                'format' => 'dd.MM.yyyy',
            ]

entity:

   /**
     * @var DateTime $birthdate
     *
     * @ORM\Column(type="datetime")
     * @Assert\NotNull()
     */
    private $birthdate;

setters and getters:

/**
 * Get birthdate
 *
 * @return DateTime
 */
public function getBirthdate(): ?DateTime
{
    return $this->birthdate;
}

/**
 * Set birthdate
 *
 * @param DateTime $birthdate
 *
 * @return $this
 */
public function setBirthdate($birthdate): self
{
    $this->birthdate = $birthdate;

    return $this;
}

Upvotes: 0

Related Questions