Reputation: 2895
I am using Symfony 3.4 and FOSRestBundle for my APIs.
All the services are working fine except this one where I am posting an entity with a form and an EntityType
field.
Controller:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
$form->handleRequest($request);
dump($form->isSubmitted(), $form->isValid());die;
}
Entity property:
/**
* @var MobileAppUser
*
* @ORM\ManyToOne(targetEntity="MobileAppUser")
* @ORM\JoinColumn(name="mobile_app_user_id", referencedColumnName="id", nullable=false)
* @Assert\NotBlank
*/
protected $mobileAppUser;
Form:
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('mobile_app_user', EntityType::class, array(
'class' => 'AppBundle:MobileAppUser',
))
->add('save', SubmitType::class)
;
}
It's working fine with a normal POST:
curl -X POST http://mysite.local/api/users/1/create-assistance-call -F 'assistance_call[mobile_app_user]=26'
dump($form->isSubmitted(), $form->isValid());die; // true and true
It's not working with JSON format:
curl -X POST \
http://mysite.local/api/users/1/create-assistance-call \
-d '{
"assistance_call": {
"mobile_app_user": {
"id": 1
}
}
}'
dump($form->isSubmitted(), $form->isValid());die; // false and false
What am I doing wrong in the JSON example?
Upvotes: 0
Views: 630
Reputation: 1673
Since you are sending your json object as a request body and not as normal POST fields - you should json_decode
request content first and then use $form->submit(...)
to load your form with the data. The old good handleRequest()
won't do here. Take a look at the following example:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
//Notice the "true" argument passed to the json_decode
$data = json_decode($request->getContent(), true);
$form->submit($data);
dump($form->isSubmitted(), $form->isValid());die;
}
You can also use FOSRestBundle BodyListener to decode json for you. To do that - add the following configuration entry:
fos_rest:
body_listener:
decoders:
json: fos_rest.decoder.jsontoform
This still doesn't make $form->handleRequest()
a good choice since it will only allow one method per form, so if you configure your form to do POST - the PUT requests will always fail without any explicit error messages.
So then you would amend the code above like this:
public function createAssistanceCallAction(Request $request)
{
$assistanceCall = new AssistanceCall();
$form = $this->createForm(AssistanceCallType::class, $assistanceCall);
$form->submit($request->request->all());
dump($form->isSubmitted(), $form->isValid());die;
}
Pay attention to the Content-Type
header you send as if it is set to 'multipart/form-data' while having json payload in its body - decoder will fail.
Upvotes: 1
Reputation: 320
Just to add to the first answer, you also need to modify your JSON payload.
You have to put directly your mobile_app_user id :
{
"assistance_call": {
"mobile_app_user": 1
}
}
Upvotes: 2