title: Symfony Form Validation failed - "This form should not contain extra fields"
body: <p>I am using React on the frontend to send data to the controller which uses Symfony Form for validation.  The information sent from React is what I expect but I am getting an error that says "This form should not contain extra fields".</p>
  
  <p>I want to create a new Booking using this form, which has a Reservation.  A Reservation has many (or none) reservationTripAddOns (TripAddOns). I have figured out that the problem is caused when I select trip add on((TripAddOn::class) reservationTripAddOn)  that I want linked to reservation. When I do not select any add on, it works.  </p>
  
  <p>Data passed from React when no add ons are selected and works:</p>
  
  <pre><code>{
      "reservations”:
          [
              {
                  "trip":277,
                  "date":"10/27/2017”,
                  "guests":2,
                  "reservationTripAddOns":[]
              }
          ]
  }
  </code></pre>
  
  <p>Data passed from React when add ons are selected and does not work:</p>
  
  <pre><code>{
      "reservations”:
          [
              {
                  "trip":277,
                  "date":"10/26/2017”,
                  "guests":2,
                  "reservationTripAddOns”:
                      [
                          {
                              "id":34,
                              "name":"Additional one guest”,
                              "price":100,
                              "trip”:null
                          }
                      ]
                 }
          ]
  }
  </code></pre>
  
  <p>BookingController:</p>
  
  <pre><code>    public function newAction(Request $request, GuideProfile $guideProfile)
      {
          $reservation = new Reservation();
          $booking = new Booking();
          $booking-&gt;addReservation($reservation);
  
          $form = $this-&gt;createForm(BookingType::class, $booking, ['guide_profile' =&gt; $guideProfile]);
          $form-&gt;submit(json_decode($request-&gt;getContent(), true));
  
          if ($form-&gt;isValid()) {
              $context = new SerializationContext();
              $context-&gt;setSerializeNull(true);
              $context-&gt;setGroups(['Session']);
              $this-&gt;get('session')-&gt;set(
                  'booking', $this-&gt;get('serializer')-&gt;serialize($booking, 'json', $context)
              );
  
              return $this-&gt;createApiResponse($booking, ['Default'], 201);
          }
  
          return $this-&gt;createApiErrorResponse($form-&gt;getErrors(true));
      }
  </code></pre>
  
  <p>BookingType:</p>
  
  <pre><code>class BookingType extends AbstractType
  {
  
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
      $builder
          -&gt;add('reservations', CollectionType::class, [
              'entry_type' =&gt; ReservationType::class,
              'entry_options' =&gt; [
                  'data_class' =&gt; Reservation::class,
                  'guide_profile' =&gt; $options['guide_profile'],
              ],
              'allow_add' =&gt; true,
          ])
      ;
  }
  
  public function configureOptions(OptionsResolver $resolver)
  {
      $resolver-&gt;setDefaults([
          'data_class' =&gt; Booking::class,
          'guide_profile' =&gt; null,
      ]);
  }
  </code></pre>
  
  <p>}</p>
  
  <p>ReservationType:</p>
  
  <pre><code>class ReservationType extends AbstractType
  {
  public function __construct(EntityManager $entityManager)
  {
      $this-&gt;entityManager = $entityManager;
  }
  
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
      $guideProfileId = $options['guide_profile'] instanceof GuideProfile ? $options['guide_profile']-&gt;getId() : 0;
  
      $builder
          -&gt;add('trip', EntityType::class, [
              'class' =&gt; Trip::class,
              'query_builder' =&gt; function (EntityRepository $er) use ($guideProfileId) {
                  return $er-&gt;createQueryBuilder('t')
                      -&gt;where('t.guideProfile = :guide_profile_id')
                      -&gt;orderBy('t.title', 'ASC')
                      -&gt;setParameter('guide_profile_id', $guideProfileId);
              },
              'choice_label' =&gt; 'title',
              'placeholder' =&gt; 'Select a Trip',
          ])
          -&gt;add('date', DateType::class, [
              'format' =&gt; 'MM/dd/yyyy',
              'html5' =&gt; false,
              'widget' =&gt; 'single_text',
          ])
          -&gt;add('reservationTripAddOns', 'collection', [
              'entry_type' =&gt; TripAddOnType::class,
              'entry_options' =&gt; [
                  'data_class' =&gt; TripAddOn::class,
                  'mapped' =&gt; false,
              ]
          ])
          -&gt;addEventListener(FormEvents::PRE_SET_DATA, [$this, 'addGuests'])
          ;
  }
  
  public function addGuests(FormEvent $event)
  {
      //assume everything works here
  }
  
  public function configureOptions(OptionsResolver $resolver)
  {
      $resolver-&gt;setDefaults([
          'data_class' =&gt; Reservation::class,
          'guide_profile' =&gt; null,
      ]);
  }
  </code></pre>
  
  <p>TripAddOnType:</p>
  
  <pre><code>class TripAddOnType extends AbstractType
  {
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder
              -&gt;add('name', TextType::class)
              -&gt;add('price', TextType::class)
          ;
      }
  
      public function configureOptions(OptionsResolver $resolver)
      {
          $resolver-&gt;setDefaults([
              'data_class' =&gt; 'AppBundle\Entity\TripAddOn'
          ]);
      }
  </code></pre>