Reputation: 341
I'm trying to figure out what am I doing wrong. I'm getting 400 bad request trying to send a post request via angular service. I have 2 entities - Document and DocumentCategory (many to many relation). I can post document itself (without categories) with no problem.
document-create.component.ts
createDocument(title, body, categories) {
let document = {title: title, body: body, categories: categories};
this._crudService.createDocument(document).subscribe(
data => {
return true;
},
error => {
console.error("Error saving document! " + error);
return Observable.throw(error);
}
);
}
crudService.ts
createDocument(document) {
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
//let body = JSON.stringify(document);
let body = document;
return this.http.post
('http://localhost:8000/documents', body, headers);
}
The form
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('title', TextType::class)
->add('body', TextType::class)
//->add('categories', TextType::class)
->add('categories', EntityType::class, array(
'class' => 'AppBundle:DocumentCategory',
'multiple' => true,
'expanded' => true,
'by_reference' => false,
'choice_label' => 'id',
))
;
}
Document.php
/**
* @ORM\ManyToMany(targetEntity="DocumentCategory", mappedBy="documents")
* @JMSSerializer\Expose
*/
private $categories;
DocumentCategory.php
/**
* @ORM\ManyToMany(targetEntity="Document", inversedBy="categories")
* @ORM\JoinTable(name="document_category_document")
* @JMSSerializer\Expose
*/
private $documents;
Request
POST /documents HTTP/1.1 Accept: application/json, text/plain, / Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.8 Connection: keep-alive Content-Length: 213 Content-Type: application/json Host: localhost:8000 Origin: http://localhost:4200 Referer: http://localhost:4200/admin/document/create User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 X-Php-Ob-Level: 1
{
"title": "t",
"body": "<p>b</p>",
"categories": [
{
"id": 1,
"name": "cat1",
"documents": []
},
{
"id": 2,
"name": "cat2",
"documents": []
}
]
}
As I said if I remove categories, everything works. I can't figure it out :(
EDIT: Postman shows this in response when I try to send above json as application/json:
{
"children": {
"title": {},
"body": {},
"categories": {
"errors": [
"This value is not valid."
],
"children": {
"1": {},
"2": {},
"3": {},
"4": {}
}
}
}
}
Upvotes: 0
Views: 1335
Reputation: 341
After looong time I finally made it. Here's my result in case someone has a simmilar problem. It's not the most elegant solution and I will try to find a better one but at least it works. The problem was in controller. Now the post method looks like this:
public function postAction(Request $request) {
$form = $this->createForm(DocumentType::class, null, [
'csrf_protection' => false,
]);
$form->submit($request->request->all());
if (!$form->isValid()) {
return $form;
}
$em = $this->getDoctrine()->getManager();
$document = $form->getData();
$categories = $request->request->get('categories');
foreach ($categories as $categoryId) {
$category = $em->getRepository('AppBundle:DocumentCategory')->find((int)$categoryId['id']);
$category->addDocument($document);
$document->addCategory($category);
$em->persist($category);
}
$em->persist($document);
$em->flush();
$routeOptions = [
'id' => $document->getId(),
'_format' => $request->get('_format'),
];
return $this->routeRedirectView('get_document', $routeOptions, Response::HTTP_CREATED);
}
And my form is simply:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('title', TextType::class)
->add('body', TextType::class)
;
}
Upvotes: 0