Patch manyToMany relation in Symfony via a React Application

Viewed 32

In a Symfony4 project, i have an entity Infrastructure, that can have many Contacts. I made a feature in my React app where you can add existing contacts to an Infrastructure.

Here is how contacts is configured in my InfrastructureType:

            ->add('contacts', CollectionType::class, array(
            'entry_type' => ContactType::class,
            'entry_options' => ['label' => false],
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
             ))

Here is the payload the React app send to the SF app:

{"contacts":[
  {
     "id":3,
     "firstname":"Maeva",
     "lastname":"CAMGUILHEM",
     "job":"Acheteuse Industrielle",
     "email":"maeva.test@test.fr",
     "phone":"03 00 00 00 00",
     "mobilePhone":"NULL"
  }

] }

When it arrives in my controller, i'm trying to PATCH (update only the contacts) of my infrastructure, by doing so:

    public function patchInfrastructure(Request $request, Infrastructure $infrastructure): JsonResponse
{
    $parameters = json_decode($request->get('appbundle_client_infrastructure'), true);
    
    $form = $this->createForm(InfrastructureType::class, $infrastructure);
    $form->submit($parameters, false);

    if ($form->isSubmitted() && $form->isValid()) {
        $this->em->persist($infrastructure);
        $this->em->flush();
    }

    return $this->error(
        500,
        $this->getErrorMessagesAsArray($form)
    );
}

This works if i remove a contact, but not when i add an existing contact. It seems like Symfony isn't able to recognize the Contact with id 3, and liking it. Instead, it creates a new Contact with null values.

I tried to pass only Ids, could have been a good idea but it then tells me the form is invalid.

If anybody could help, thank you so much

1 Answers

Ok, i got it working.

So, if you wonder how to patch a ManyToMany / oneToMany relationship in Symfony and link entities that already exists, in a "Api Rest" way, just do the following:

In the formType, i changed my contacts property:

            ->add('contacts', EntityType::class, array(
            'class' => Contact::class,
            'choice_label' => function ($contact) {
                return $contact->getName();
            },
            'multiple' => true,
            'by_reference' => false,
        ))

Using EntityType instead of CollectionType unblocked the situation and allows you to pass an array of ids of the entities you want to link.

In my case, i just had to send:

appbundle_client_infrastructure: {"contacts":[3]}

To my controller, and he links automatically the contact id 3 to my entity.

Related