title: Symfony2 Form Collection allow_add and allow_delete null error (Silex)
body: <p>I've run into a problem when following the Symfony cookbook for form collections with add/remove. See: <a href="http://symfony.com/doc/current/cookbook/form/form_collections.html" rel="nofollow">http://symfony.com/doc/current/cookbook/form/form_collections.html</a></p>
  
  <p>Now, for some reason, if I dynamically add a form row <strong>but don't fill in any of its fields</strong>, I get the following error:</p>
  
  <p><code>ContextErrorException: Catchable Fatal Error: Argument 1 passed to Project::addTask() must be an instance of Task, null given in D:\web_workspace\wedding\src\testapp.php line 82</code></p>
  
  <p>I would like people to be able to have blank rows in the form which will just get ignored. For example, if you click "Add Task" a few times, but don't fill in the last row, the form should still be submitted, and the last row should be ignored.</p>
  
  <p>I've created a very simple Silex demo that fits in just a couple of files. I'll highlight it here, but the full example is here, and can be run by just adding Silex via composer: <a href="https://gist.github.com/mattsnowboard/7065865" rel="nofollow">https://gist.github.com/mattsnowboard/7065865</a></p>
  
  <p>I have the following Models (just <code>Project</code> which has a description and a collection of <code>Task</code>s)</p>
  
  <pre><code>class Task
  {
      protected $name;
  
      public function getName()
      {
          return $this-&gt;name;
      }
  
      public function setName($name)
      {
          $this-&gt;name = $name;
          return $this;
      }
  }
  
  class Project
  {
      protected $description;
  
      protected $tasks;
  
      public function __construct()
      {
          $this-&gt;tasks = array();
      }
  
      public function getDescription()
      {
          return $this-&gt;description;
      }
  
      public function setDescription($description)
      {
          $this-&gt;description = $description;
          return $this;
      }
  
      public function getTasks()
      {
          return $this-&gt;tasks;
      }
      public function addTask(Task $task)
      {
          if (!is_null($task) &amp;&amp; !in_array($task, $this-&gt;tasks)) {
              $this-&gt;tasks[] = $task;
          }
          return $this;
      }
      public function removeTask(Task $task)
      {
          if (!is_null($task)) {
              $this-&gt;tasks = array_diff($this-&gt;tasks, array($task));
          }
          return $this;
      }
  }
  </code></pre>
  
  <p>My forms are as follows</p>
  
  <pre><code>class TaskType extends AbstractType
  {
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder-&gt;add('name', 'text', array(
              'required' =&gt; false
          ));
      }
  
      public function setDefaultOptions(OptionsResolverInterface $resolver)
      {
          $resolver-&gt;setDefaults(array(
              'data_class' =&gt; '\Task',
          ));
      }
  
      public function getName()
      {
          return 'task';
      }
  }
  
  class ProjectType extends AbstractType
  {
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder-&gt;add('description', 'text', array())
              -&gt;add('tasks', 'collection', array(
                  'type' =&gt; new TaskType(),
                  'allow_add'    =&gt; true,
                  'by_reference' =&gt; false,
                  'allow_delete' =&gt; true,
                  'required' =&gt; false
              ))
              -&gt;add('submit', 'submit')
          ;
      }
  
      public function setDefaultOptions(OptionsResolverInterface $resolver)
      {
          $resolver-&gt;setDefaults(array(
              'data_class' =&gt; '\Project',
          ));
      }
  
      public function getName()
      {
          return 'project';
      }
  }
  </code></pre>
  
  <p>The controller adds some test data to the form and just prints the data when it is submitted:</p>
  
  <pre><code>$app-&gt;match('/', function (Request $request) use ($app) {
      $project = new Project();
  
      // dummy code
      $task1 = new Task();
      $task1-&gt;setName('A Task');
      $project-&gt;addTask($task1);
      // end dummy code
  
      $form = $app['form.factory']-&gt;create(new ProjectType(), $project);
  
      $form-&gt;handleRequest($request);
  
      if ($form-&gt;isValid()) {
          $data = $form-&gt;getData();
          $debug = print_r($data, true);
          echo $debug;
      }
  
      return $app['twig']-&gt;render('test.html.twig', array(
          'form' =&gt; $form-&gt;createView(),
      ));
  })
  -&gt;method('GET|POST');
  </code></pre>
  
  <p>The view is mostly this, and the javascript sample from the cookbook</p>
  
  <pre><code>{{ form_start(form) }}
  
      {{ form_row(form.description) }}
  
      &lt;h3&gt;Tags&lt;/h3&gt;
      &lt;ul class="tasks" data-prototype="{{ form_widget(form.tasks.vars.prototype)|e }}"&gt;
          {# iterate over each existing tag and render its only field: name #}
          {% for task in form.tasks %}
              &lt;li&gt;{{ form_row(task.name) }}&lt;/li&gt;
          {% endfor %}
      &lt;/ul&gt;
  
      {{ form_widget(form.submit) }}
  {{ form_end(form) }}
  </code></pre>
  
  <p>Am I just missing something? Is this a bug? I feel like this example which is very close to the cookbook should work pretty easily...</p>
  
  <p><strong>Updated</strong>: Removing <code>"allow_deleted"</code> doesn't actually fix this.</p>