0

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": {}
      }
    }
  }
}
3
  • Please use something like postman to send the data to the backend. This will specify whether it is and Angular Problem or Backend. I assume its backend related. Commented Jun 8, 2017 at 21:21
  • see edit - why categories are not valid? Commented Jun 8, 2017 at 21:44
  • It has to be backend - json is valid, I can post documents and categories apart, but not in reference. Commented Jun 8, 2017 at 21:56

1 Answer 1

0

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)
    ;         
}
Sign up to request clarification or add additional context in comments.

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.