Reputation: 771
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:
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>
Upvotes: 2
Views: 4982
Reputation: 123
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);
Upvotes: 0
Reputation: 10085
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.
Upvotes: 1
Reputation: 771
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.
Upvotes: 0
Reputation: 3029
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>
Upvotes: 1