MiGU
MiGU

Reputation: 380

symfony2's FOSRestController can't validate an ajax post request

I'm developing a Symfony 2.6.1 application and I have a form I render with the FormTypes and an Entity using annotations as validation. The form is submitted an AJAX POST call to a FOSRestController. The thing is the isValid() function is returning FALSE and I get no error messages...

My FOSRestController looks as follows:

class RestGalleryController extends FOSRestController{

    /**
     * @Route(requirements={"_format"="json"})
     */
    public function postGalleriesAction(\Symfony\Component\HttpFoundation\Request $request){

        return $this->processForm(new \Law\AdminBundle\Entity\Gallery());   
    }
    private function processForm(\Law\AdminBundle\Entity\Gallery $gallery){

        $response = array('result' => 'Default');

        $gallery->setName('TEST'); //Just added this to be sure it was a problem with the validator
        $form = $this->createForm(
            new \Law\AdminBundle\Form\Type\GalleryType(), 
            $gallery
        );
        $form->handleRequest($this->getRequest());

        if ($form->isValid()) {

            $response['result'] = 'Is Valid!';
        }else{
            var_dump( $form->getErrorsAsString() );
            die;           
        }
        return $response;
    }

My Gallery Entity class below:

<?php

namespace Law\AdminBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;

/**
 * Gallery
 *
 * @ORM\Table(name="gallery")
 * @ORM\Entity
 */
class Gallery{

    /**
     * @var string
     * @Assert\NotBlank()
     * @ORM\Column(name="name", type="text", nullable=false)
     */
    private $name;

    public function __construct(){
        $this->images = new ArrayCollection();
    }
    /**
     * Set name
     *
     * @param string $name
     * @return Gallery
     */
    public function setName($name){
        $this->name = $name;

        return $this;
    }
    /**
     * Get name
     *
     * @return string 
     */
    public function getName(){
        return $this->name;
    }
}

The GalleryType, encapsulating the form:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class GalleryType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options){
        $builder->add('name');
    }
    /**
     * {@inheritdoc}
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'        => 'Law\AdminBundle\Entity\Gallery',
            'csrf_protection'   => false,
        ));
    }
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'Gallery';
    }
}

Finally, In my app/config/config.yml, the validation is set up as follows:

validation:      { enable_annotations: true }

To get the validation error I've also tried with the following function, unsuccessfully :

private function getErrorMessages(\Symfony\Component\Form\Form $form) {
    $errors = array();

    foreach ($form->getErrors() as $key => $error) {
        if ($form->isRoot()) {
            $errors['#'][] = $error->getMessage();
        } else {
            $errors[] = $error->getMessage();
        }
    }

    foreach ($form->all() as $child) {
        if (!$child->isValid()) {
            $errors[$child->getName()] = $this->getErrorMessages($child);
        }
    }

    return $errors;
} 

EDIT:

If I manually use a validator, it works:

    $formGallery = new Gallery();
    $formGallery->setName($this->getRequest()->get('name', NULL));
    $validator = $this->get('validator');
    $errors = $validator->validate($formGallery);

So it's like somehow my GalleryType wasn't using the validator.

Upvotes: 9

Views: 189

Answers (1)

Kamil Adryjanek
Kamil Adryjanek

Reputation: 3338

This is because you are using handleRequest with empty submitted data I guess. In such scenario you such call:

// remove form->handleRequest call
// $form->handleRequest($this->getRequest());
$form->submit($request->request->all());

as handleRequest will auto-submit form unless one field is present. When you handle request with empty array form is not being submitted, thats why isValid return false with no errors.

Note: check if you are sending empty POST array or something like:

`Gallery` => []

If you are sending empty Gallery array everything should work as expected.

Could you paste data that you are sending via AJAX request?

Upvotes: 1

Related Questions