2

I've been following this guide as close as possible to create a simple REST API in Symfony2.

Unfortunately whatever I post to the API I always get:

{"children":{"firstName":{"errors":["This value should not be blank."]},"lastName":{"errors":["This value should not be blank."]},"email":{"errors":["This value should not be blank."]},"password":{"errors":["This value should not be blank."]},"dob":{"errors":["This value should not be blank."],"children":{"year":[],"month":[],"day":[]}},"tutorialWatched":{"errors":["This value should not be blank."]},"challengeEmails":{"errors":["This value should not be blank."]},"mailingList":{"errors":["This value should not be blank."]}}}

My validation is as follows:

LifeMirror\APIBundle\Model\Users:
    properties:
        firstName:
            - NotBlank:
        lastName:
            - NotBlank:
        email:
            - NotBlank:
            - Email:
        password:
            - NotBlank:
        dob:
            - NotBlank:
            - Date:
        tutorialWatched:
            - NotBlank:
            - Choice:
                choices: [0, 1]
        challengeEmails:
            - NotBlank:
            - Choice:
                choices: [0, 1]
        mailingList:
            - NotBlank:
            - Choice:
                choices: [0, 1]

And my controller is:

class RegisterController extends Controller
{
    public function indexAction()
    {
        return $this->processForm(new Users());
    }

    private function processForm(Users $user)
    {
        $statusCode = $user->isNew() ? 201 : 204;

        $form = $this->createForm(new UsersType(), $user);
        $form->bind($this->getRequest());

        if ($form->isValid()) {
            $user->save();

            $response = new Response();
            $response->setStatusCode($statusCode);
            return $response;
        }
        $view = View::create($form, 400);
        $view->setFormat('json');
        return $view;
    }
}

I can var_dump $this->getRequest() and can see the data are there, but I'm not sure why the validator is complaining.

EDIT:

Here's the form:

namespace LifeMirror\APIBundle\Form\Type;

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

class UsersType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('firstName');
        $builder->add('lastName');
        $builder->add('email');
        $builder->add('password');
        $builder->add('dob');
        $builder->add('tutorialWatched');
        $builder->add('challengeEmails');
        $builder->add('mailingList');
    }

    /**
     * {@inheritdoc}
     */
    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'LifeMirror\APIBundle\Model\Users',
            'csrf_protection'   => false,
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'users';
    }
}

And my input: enter image description here

EDIT 2: Content tof $_REQUEST:

array(9) { ["firstName"]=> string(5) "James" ["lastName"]=> string(6) "Hadley" ["email"]=> string(9) "[email protected]" ["password"]=> string(7) "test123" ["dob"]=> string(33) "{'year':1991,'month':08,'day':02}" ["location"]=> string(9) "Lancaster" ["tutorialWatched"]=> string(1) "0" ["challengeEmails"]=> string(1) "0" ["mailingList"]=> string(1) "0" }

EDIT 3: HTML form:

<form action="http://www.lifemirror.org/api/register/" method="post">
    <input type="hidden" name="firstName" value="James" />
    <input type="hidden" name="lastName" value="Hadley" />
    <input type="hidden" name="email" value="[email protected]" />
    <input type="hidden" name="password" value="test123" />
    <input type="hidden" name="dob" value="{'year':1991,'month':08,'day':02}" />
    <input type="hidden" name="location" value="Lancaster" />
    <input type="hidden" name="tutorialWatched" value="0" />
    <input type="hidden" name="challengeEmails" value="0" />
    <input type="hidden" name="mailingList" value="0" />
    <input type="submit" />
</form>
6
  • Is your indexAction that is processing the user creation operation? Could you post you request data and you form as well? Commented Jan 27, 2013 at 21:17
  • I've added the extra information and yes, indexAction should be processing the form. Commented Jan 27, 2013 at 21:22
  • Still missing some important information ;-). It's important to know the form name and the content of variable $_REQUEST . I seems like the name of the form is missing from client. Commented Jan 27, 2013 at 21:25
  • I've added $_REQUEST. I don't think there's a form name defined in Symfony2 (might be wrong - very new to Symfony2) and there definitely isn't one defined client side. Commented Jan 27, 2013 at 21:30
  • Could you post you whole Form class? How are you sending this info from the client? Commented Jan 27, 2013 at 21:38

4 Answers 4

1

The problem is that you are not considering the form name in your action. By the way, your form name is 'users'.

Change your action to

class RegisterController extends Controller
{
    public function indexAction()
    {
        return $this->processForm(new Users());
    }

    private function processForm(Users $user)
    {
        $statusCode = $user->isNew() ? 201 : 204;

        $form = $this->createForm(new UsersType(), $user);
        $form->bind(array('users'=>$this->getRequest()->query->all()));

        if ($form->isValid()) {
            $user->save();

            $response = new Response();
            $response->setStatusCode($statusCode);
            return $response;
        }
        $view = View::create($form, 400);
        $view->setFormat('json');
        return $view;
    }
}

Now it should work fine.

The new binding is the key to get it working

$form->bind(array('users'=>$this->getRequest()->query->all()));

PS: Note that if you use the Twig for rendering that form, you don't need to change the code, as the form name will be rendered together with the HTML markup.

Your HTML form should be something like

<form>
    <input name="users[firstName]">
    <input name="users[lastName]">
    <input name="users[email]">
    <input name="users[password]">
    <input name="users[tutorialWatched]">
    <input name="users[challengeEmails]">
    <input name="users[mailingList]">
</form>    
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your help, however, I have tried this as well as adding name="users" to the HTML form and I get the following: {"errors":["This form should not contain extra fields."],"children":{"firstName":{"errors":["This value should ... NB The form will be submitted from mobile phones when done.
Could you post your HTML form? PS: I updated the answer to speed things up. Take a look.
About the error "This form should not contain extra fields.": you added an extra field called "location" that you did not add to the UsersType class. Do not do that! ;-)
I added location to the UsersType class (sorry about that), but the problem still persists. I can get rid of the "extra fields" error by binding to $this->getRequest()->request->all() (request, not query - query is empty). But it's still saying all of the fields are empty. I checked $this->getRequest()->request->all() and it is an array with all of the fields and data in it. Adding [users] seems to create further problems as well.
Could you post your HTML form?
|
1

If you're using the FOSRestBundle and the body listener, the request doesn't accept any application/x-www-form-urlencoded content any more. You can't send data using a HTML form.

REST Webservice means, that you send your request data as JSON or XML like you get the response.

For testing you can add the NelmioApiDocBundle to your project, they have a excellent sandbox for testing.

Comments

0

Strangely, in my case each field had to be specified manually in the controller:

    $form->bind(array(
        "firstName" => $this->getRequest()->request->get('firstName'),
        "lastName" => $this->getRequest()->request->get('lastName'),

etc.

Comments

0

I also run into this issue. I was able to make it work by binding (POST) request variables like this:

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

Still, I find it very strange that the default method does not work...

EDIT: Ok, I figured it out. It's a namespacing thing. If I POST variables with a namespace like this myformname[fieldname] instead just fieldname, then it works with

$form->bind($request);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.