1

i am working with embedded forms within symfony and cannot get the data from the embedded form.

This is my Patent Form

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use AppBundle\Form\SubscriberAddressType;

class SubscriberDetailsType extends AbstractType {
    /**
     * @param FormBuilderInterface $builder
     * @param array                $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder
            ->add('firstname', TextType::class, [
                'label' => false,
                'required' => true,
                'error_bubbling' => true,
                'attr' => [
                    'placeholder' => 'First Name',
                    'class' => 'form-control'
                    ]])
            ->add('lastname', TextType::class, [
                'label' => false,
                'required' => true,
                'error_bubbling' => true,
                'attr' => array(
                    'placeholder' => 'Last Name',
                    'class' => 'form-control'
                )])
            ->add('emailaddress', EmailType::class, [
                'label' => false,
                'required' => true,
                'error_bubbling' => true,
                'attr' => [
                    'placeholder' => 'Email Address',
                    'pattern'     => '.{2,}',//minlength
                    'class' => 'form-control'
                    ]])
            ->add('subscriberaddress', CollectionType::class, ['entry_type' => SubscriberAddressType::class])
            ->add('submit', SubmitType::class, [
                'label' => 'Sign Up',
                'attr' => [
                    'class' => 'smoothScroll btn btn-danger sb-button'
                    ]
        ])
             ;
    }

    /**
    * @param OptionsResolverInterface $resolver
    */
    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(['data_class' => 'AppBundle\Entity\SubscriberDetails']);
    }
    /**
     * @return string
     */
    public function getName() {
        return 'subscriberdetails';
    }
}

This is my child form

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class SubscriberAddressType extends AbstractType {
    /**
     * @param FormBuilderInterface $builder
     * @param array                $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder
            ->add('address1', TextType::class, [
                'label' => false,
                'required' => true,
                'error_bubbling' => true,
                'attr' => [
                    'placeholder' => 'Address 1',
                    'class' => 'form-control'
                    ]])
            ->add('city', TextType::class, [
                'label' => false,
                'required' => true,
                'error_bubbling' => true,
                'attr' => array(
                    'placeholder' => 'City',
                    'class' => 'form-control'
                )])
             ;
    }

    /**
    * @param OptionsResolverInterface $resolver
    */
    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(['data_class' => 'AppBundle\Entity\SubscriberAddress']);
    }
    /**
     * @return string
     */
    public function getName() {
        return 'subscriber';
    }
}

This is how i call the embedded form in my twig template

        <div class="form-group ">        
            {% for field in form.subscriberaddress %}
                {{ form_label(field.city) }}
                {{ form_widget(field.city) }}
            {% endfor %}           
        </div>

When i am trying to get the data from the form using below:

            $firstname = $form['firstname'] ->getData();
            $lastname =$form['lastname'] ->getData();
            $email = $form['emailaddress'] ->getData();
            $address = $form['subscriber address']['address1'] ->getData();
            $city =$form['subscriber address']['city'] ->getData();

it works fine for above first 3 lines but when it gets to $address = $form['subscriber address']['address1'] ->getData(); with is an embedded field, symfony shoots an error child element does not exist.

I have tried going though official symfony cookbook as well as these posts Post1, Post2 but none of these seem to answer my question, which is: how do i get the data from embedded fields in the form?

Community
  • 1
  • 1
Sky21.86
  • 627
  • 2
  • 9
  • 26

1 Answers1

5

Your embedded form is actually embedded in collection (not sure if this is your intention) so you need to treat it as collection/array

If collection was mistake

You might want to change it to

->add('subscriberaddress', SubscriberAddressType::class)

And then $form->getData() will work. Alternatively you can call $form->get('subscriberaddress')->getData()

if you actually want collection

If you actually want to use it as CollectionType to keep multiple copies of SubscriberAddressType then access data by

foreach ($form->get('subscriberaddress') as $subForm) {
    $subData[] = $subForm->getData();
}

Also consider changing name subscriberaddress to subscriberAddresses to indicate that it's collection

Konrad Podgórski
  • 2,024
  • 17
  • 17
  • Thanks alot Kondar. I'll try it today and will update this thread with results! – Sky21.86 Aug 01 '16 at 06:36
  • Just tried this solution and it worked for me! Thanks a a lot for solution as well as detailed explanation of what and why. – Sky21.86 Aug 01 '16 at 17:50