Unable to transform value for property path : Expected a \DateTime or \DateTimeInterface

12,332

If you use Symfony forms you don't have to retrieve data from request "manually". The only thing you should do is to handle request:

$event = new Exvent();
$form = $this->createForm(EventCreateFormType::class, $event);
$form->handleRequest($request);

Handle request just binds data from request with entity properties. It takes value from form array, looks what type the property should be and converts it into appropriate format.

If you want to do that manually (then you don't have to create form - it's just useless) you should do something like this:

$startTime = new \DateTime($submittedForm['startTime']);
$endTime = new DateTime($submittedForm['endTime']);

If, as you said, startTime and endTimes are array you have to build datetime string from those arrays before put them into DateTime constructor.

Then startTime and endTime will be type of DateTime.

Share:
12,332

Related videos on Youtube

sfpxl
Author by

sfpxl

Updated on June 04, 2022

Comments

  • sfpxl
    sfpxl almost 2 years

    First of all: I'm pretty new to Symfony/programming and have problems finding the solution I need.

    I have these variables in my 'Event' Entity with standard getters and setters.:

     /**
     * @var \DateTime
     *
     * @ORM\Column(name="startTime", type="time", nullable=true)
     *
     * @Assert\Expression(
     *     "this.getStartTime() <= this.getEndTime()",
     *     message="Start time should be less or equal to end date!"
     * )
     */
    private $startTime;
    
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="endTime", type="time", nullable=true)
     *
     * @Assert\Expression(
     *     "this.getEndTime() >= this.getStartTime()",
     *     message="End time should be greater or equal to start time!"
     * )
     */
    private $endTime;
    

    I have this Controller for my form:

    <?php
    
    
    namespace AppBundle\Controller;
    
    
    use AppBundle\Entity\Event;
    use AppBundle\Form\EventCreateFormType;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Annotation\Route;
    
    class EventController extends Controller {
    
    /**
     * @Route("/eventmanager", name="event")
     */
    public function eventsAction(Request $request)
    {
        $events = $this->getDoctrine()// query database and get all events
        ->getRepository('AppBundle:Event')
            ->findAll();
    
        $event = new Event();
    
        $adminstatus = false;
    
        if (in_array('ROLE_ADMIN', $this->getUser()->getRoles())) {
            $adminstatus = true;
        }
        $event = $this->get('holiday.service')->createEventForm($request);
        $form = $this->createForm(EventCreateFormType::class, $event, array('rolestatus' => $adminstatus));
    
    
        if ($form->isValid()) {
    
            $em = $this->getDoctrine()->getManager();
            $em->persist($event);
            $em->flush();
    
            return $this->redirectToRoute('event'); // redirect to route: events
        }
    
        return $this->render('default/eventmanager.html.twig', array('events' => $events, 'form' => $form->createView()));
    }
    

    With this type:

    <?php
    
    
    namespace AppBundle\Form;
    
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
    use Symfony\Component\Form\Extension\Core\Type\SubmitType;
    use Symfony\Component\Form\Extension\Core\Type\TextareaType;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    use Symfony\Component\Form\Extension\Core\Type\TimeType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class EventCreateFormType extends AbstractType {
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);
    
        $builder
            ->add('title', TextType::class, array(
                'label' => 'event.form.title.label',
                'attr' => array(
                    'maxlength' => 75,
                    '' => '')
            ))
            ->add('dateOf', TextType::class, array(
                'label' => 'event.form.dateOf.label',
    //                'widget' => 'single_text',
    //                'html5' => false,
                'attr' => [
                    'class' => 'js-datepicker',
    //                    'format' => 'dd-MM-yyyy',
                ],
            ))
            ->add('startTime', TimeType::class, array(
                'label' => 'event.form.startTime.label',
            ))
            ->add('endTime', TimeType::class, array(
                'label' => 'event.form.endTime.label',
            ))
            ->add('notice', TextareaType::class, array(
                'label' => 'event.form.notice.label',
                'required' => false,
                'attr' => array('maxlength' => 2500)
            ));
        if ($options['rolestatus'] == true) {
            $builder->add('status', ChoiceType::class, array(
                'label' => 'event.form.status.label',
                'data' => $options['rolestatus'],
                'choices' => array(
                    'event.form.status.public' => true,
                    'event.form.status.private' => false
                ),
                'choices_as_values' => true
            ));
        }
        $builder->add('save', SubmitType::class, array(
            'label' => 'event.form.create.button'
        ));
    
    
    }
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $configs = $resolver->getDefinedOptions();
        $configs[] = 'rolestatus';
        $resolver->setDefined($configs);
    }
    

    }

    And this service:

    <?php
    
    namespace AppBundle\Controller\Services;
    
    use AppBundle\Entity\Event;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\Request;
    
    class HolidayServiceController extends Controller {
    
    
    
    public function createEventForm(Request $request) {
    
        $submittedForm = $request->get('event_create_form');
        $adminstatus = false;
        if (in_array('ROLE_ADMIN', $this->getUser()->getRoles())) {
            $adminstatus = true;
        }
        dump($submittedForm);
    
        $event = new Event();
        if (!empty($submittedForm)) {
    
                $creator = $this->getUser();
                $title = $submittedForm['title'];
                $startTime = $submittedForm['startTime'];
                $endTime = $submittedForm['endTime'];
                $notice = $submittedForm['notice'];
                $now = new\DateTime();
                $dateOf = new \DateTime();
                $explodedDate = explode('-', $submittedForm['dateOf']);
                $dateOf->setDate($explodedDate[2], $explodedDate[1], $explodedDate[0]);
    
                $event->setTitle($title);
                $event->setDateOf($dateOf);
                $event->setStartTime($startTime);
                $event->setEndTime($endTime);
                $event->setNotice($notice);
                $event->setCreator($creator);
                $event->setCreatedAt($now);
                if (!empty($submittedForm) && $adminstatus == true) {
                    $status = $submittedForm['status'];
                    $event->setStatus($status);
                } else {
                    $event->setStatus(false);
                }
                return $event;
            }
        return $event;
    
    
    }
    }
    

    Now, when i try to create a new Event I get following error:

    Unable to transform value for property path "startTime": Expected a \DateTime or \DateTimeInterface. 500 Internal Server Error - TransformationFailedException

    I know that this is happening because I'm passing an array of startTime but not an object.

    What do I have to change to accomplish that?

    thx in advance.

  • sfpxl
    sfpxl over 7 years
    I don't know the reasons but someone told me to do it this way. But he isnt here to help me now. I've tried the second thing u said but now i get this: Type error: DateTime::__construct() expects parameter 1 to be string, array given
  • sfpxl
    sfpxl over 7 years
    If i change the input in the EventCreateFormType from TimeType to TextType it works just fine. But i want the dropdown boxes and not a text input
  • Alex
    Alex over 7 years
    If you're new in Symfony it's better to use first choice: use Symfony forms. Here is documentation: symfony.com/doc/current/forms.html (choose the appropriate version). Read it carefully and change your code appropriately.