Search code examples
symfony4fosrestbundle

symfony4 - form->isValid() return false and form->getErrors return empty array


I use symfony 4 with FOSRestBundle. I have controller:

/**
 * @Route("/api")
 */
class ProjectController extends FOSRestController
{
    /**
     * @FOSRest\Post("/project")
     */
    public function postProjectAction(Request $request, ValidatorInterface $validator)
    {
        $project = new Project();

        $project->setCreatedBy($this->getUser()->getUser());

        $project->setCreatedAt(new \DateTime());

        $form = $this->createForm(ProjectType::class, $project);

        $form->submit($request->request->all());

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($project);
            $em->flush();
            return new JsonResponse([
                'status' => 'created'
            ], 200);
        }
        return new JsonResponse($form->getErrors(true, false), 400);
    }

}

When i dump $form->isValid() i got false, but response body is []

How can i got error for fields? Or maybe what i doing wrong?

There is ProjectType:

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class,
                [
                    'label' => 'label.name'
                ]
            )
            ->add('nameKey', TextType::class,
                [
                    'label' => 'label.nameKey'
                ]
            )
            ->add('description', TextareaType::class,
                [
                    'label' => 'label.description'
                ]
            )
            ->add('deadline', DateTimeType::class,
                [
                    'label' => 'label.deadline',
                    'widget' => 'single_text',
                    'html5' => false,
                    'attr' => [
                        'class' => 'bootstrap-datetimepicker'
                    ],
                    'format' => 'yyyy-mm-dd HH:ii'
                ]
            )
            ->add('active', ChoiceType::class,
                [
                    'label' => 'label.active',
                    'choices' => [
                        'label.yes' => true,
                        'label.no' => false
                    ]
                ]
            )
            ->add('priority', EntityType::class,
                [
                    'class' => Priority::class,
                    'choice_label' => 'name',
                    'label' => 'label.priority',
                ]
            )
            ->add('assignedUsers', EntityType::class, 
                [
                    'class' => User::class,
                    'choice_label' => 'email',
                    'label' => 'label.',
                    'multiple' => true,
                ]
            )
            ->add('assignedCustomers', EntityType::class, 
                [
                    'class' => Customer::class,
                    'choice_label' => 'email',
                    'label' => 'label.',
                ]
            )
        ;

        $builder->get('priority')->addModelTransformer($this->priorityToNumberTransformer);
        $builder->get('assignedUsers')->addModelTransformer($this->userToNumberTransformer);
        $builder->get('assignedCustomers')->addModelTransformer($this->customerToNumberTransformer);
    }

And request data which i send:

{ "name": "asd", "nameKey": "AS", "description": "Simple desc", "priority": "1", "deadline": "2016-09-01 21:02:20", "active": true, "assignedCustomers": {}, "assignedUsers": {} }


Solution

  • Its likely that you have troubles with the CSRF protection. Try to create the form and disable CSRF protection. Having CSRF protection on an stateless API is pretty useless but enabled by default.

    You can either disable it when creating the form:

    $form = $this->createForm(ProjectType::class, $project, [
        'csrf_protection' => false,
    ]);
    

    or you disable it via the config, by defining a user role:

    fos_rest:
        disable_csrf_role: ROLE_API
    

    See https://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#csrf-validation

    When you encounter an form validation error, you should return a different view. According to the docu https://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#forms-and-views this could be something like:

    return new View($form, Response::HTTP_BAD_REQUEST);