Note that there are some explanatory texts on larger screens.

plurals
  1. PONon-object error on a certified object
    primarykey
    data
    text
    <p>I'm working on a Symfony form with non-entity fields (in a collection).</p> <p>(EDIT: All the code below is now working well!)</p> <h2>What we're talking about</h2> <p>For comprehension this is some code snippets : Form definition (in PieceType class):</p> <pre><code>// Form\Type\PieceType.php $builder -&gt;add('name', 'text', array('max_length' =&gt; 70, 'label' =&gt; "piece.name")) -&gt;add('compositors', 'collection', array('type' =&gt; 'entity', 'options' =&gt; array('class' =&gt; 'kalisonStdArchiveBundle:Person', 'property_path' =&gt; false), 'allow_add' =&gt; true, 'allow_delete' =&gt; true, 'property_path' =&gt; false, 'by_reference' =&gt; false, 'label' =&gt; 'piece.compositor' )); </code></pre> <p>The compositors fields are added using javascript, using the data-prototype (explained <a href="http://symfony.com/doc/current/reference/forms/types/collection.html#adding-and-removing-items" rel="nofollow">here</a>).</p> <p>The rendering is simply done using that view:</p> <pre><code>// Resources\views\Piece\piece.new.html.twig {% block javascripts %} {{ parent() }} &lt;script type="text/javascript"&gt;var nbCompositors = {{ form.compositors|length }}&lt;/script&gt; &lt;script type="text/javascript" src="{{ asset('bundles/kalisonstdarchive/js/piece.new.js') }}"&gt;&lt;/script&gt; {% endblock javascripts %} {% block main %} &lt;form novalidate action="{{ path("kalisonStdArchiveBundle_piece_new") }}" method="post" {{ form_enctype(form) }}&gt; {{ form_widget(form) }} &lt;button id="add-compositor"&gt;{{ "compositor.add"|trans }}&lt;/button&gt; &lt;input type="submit" id="submit" value="{{ "piece.create"|trans }}" name="submit" /&gt; &lt;/form&gt; {% endblock %} </code></pre> <p>The javascript associated is:</p> <pre><code>// Resources\public\js\piece.new.js $(document).ready(function() { jQuery('#add-compositor').click(function() { var list = jQuery('#kalison_stdarchivebundle_piecetype_compositors'); var newCompositor = list.attr('data-prototype'); newCompo = newCompositor.replace(/\$\$name\$\$/g, nbCompositors); nbCompositors++; var html = jQuery('&lt;p&gt;&lt;/p&gt;').html(newCompositor); html.appendTo(jQuery('#kalison_stdarchivebundle_piecetype_compositors')); return false; }); }); </code></pre> <p>And here is the action which manage the datas. As notified by @l3l0, I wasn't checking last iteration, which causes a $addCompositor null: </p> <pre><code>// Controller\PieceController.php $newPiece = new Piece(); $form = $this-&gt;get('form.factory')-&gt;create(new PieceType(), $newPiece); if ('POST' == $request-&gt;getMethod()) { $form-&gt;bindRequest($request); if ($form-&gt;isValid()) { $this-&gt;get('piece_manager')-&gt;savePiece($newPiece); if ($form["compositors"] != null) { foreach ($form["compositors"] as $formCompositor) { $addCompositor = $formCompositor-&gt;getData(); if ($addCompositor != null) { $newPerfomance = new Performance(); $newPerfomance-&gt;setPerson($addCompositor); // Throw Catchable Fatal Error $newPerfomance-&gt;setPiece($newPiece); $newPerfomance-&gt;setInstrument($instrument); $this-&gt;get('performance_manager')-&gt;savePerformance($newPerfomance); } } } } } </code></pre> <p>My problem is that I got a Symfony error telling that: <code>Argument 1 passed to Performance::setPerson() must be an instance of Person, null given</code>. (Of course, the method in Performance class is <code>public function setPerson(Person $person)</code>)</p> <h2>What I've tried</h2> <ul> <li><p>I tried to check for sure: <code>if (!is_object($addCompositor)) throw new Exception('NOT AN OBJECT');</code></p> <p>And yes, <code>$addCompositor</code> is really an object.</p></li> <li><p>I assumed it was an incompatible object, but if try to print the object: <code>var_dump($addCompositor)</code>.</p> <p>I'm not surprised to get: <code>object(...\Entity\Person)</code></p></li> <li><p>finally my last test was to call a method on this object: <code>echo $addCompositor-&gt;getLastName();</code>.</p> <p>Worked as well, printing the name - and just after throw this well known error: <code>Call to a member function getLastName() on a non-object</code>.</p></li> </ul> <p>So, my code looks like that now:</p> <pre><code>foreach ($form["compositors"] as $formCompositor) { $addCompositor = $formCompositor-&gt;getData(); if (!is_object($addCompositor)) throw new Exception('NOT AN OBJECT'); // Not throwing: it's an object var_dump($addCompositor); // Print a Person object echo $addCompositor-&gt;getLastName(); // Print the name, then break on "non-object" error $newPerfomance = new Performance(); $newPerfomance-&gt;setPerson($addCompositor); // Throw Catchable Fatal Error $newPerfomance-&gt;setPiece($newPiece); $newPerfomance-&gt;setInstrument($instrument); $this-&gt;get('performance_manager')-&gt;savePerformance($newPerfomance); } </code></pre> <h2>Where is your god now?</h2> <p>At first I thought it was a Symfony bug, but with that last test I'm a bit confused. Have you ever been facing that?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload