Felurian Felurian - 2 years ago 274
Twig Question

Twig json_encode with entity objects and collections (Symfony3)

From my controller I pass an array of entities called

Tag
to the twig file like this:

return $this->render('tags/list.html.twig', array(
'tags' => $tags,
));


Then, I show each tag in HTML with Twig
for
. Each
Tag
has a collection of entity
Texts
(in multiple languages). I want to pass the Texts collection to JS to do some treatments with jQuery.

{% for tag in tags %}
{% if tag.texts|default %}
<div data-tag-texts="{{ tag.texts|json_encode }}">...</div>
{% endif %}

...
{% endfor %}


But it returns an empty object in JS :
Object {}
whereas my collection of Texts isn't empty. Usually, the Texts is an object of objects.

I tried a lot of things but with the same result :

{{ tag.texts|json_encode }}
{{ tag.texts|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}


I would like to browse texts in order to show everyone in languages tabs. And all of this in a Boostrap Modal. So, I have to get the texts in javascript.

Thanks for your help.

Answer Source

Thanks to the idea of @Matteo, I installed the Serializer Component of Symfony (instead of implement the \JsonSerializable interface).

In my Tag entity, I added :

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

public function serializer() {
    $encoder = new JsonEncoder();

    $normalizer = new ObjectNormalizer();
    $normalizer->setIgnoredAttributes(array(
        'typeCode', 'type', 'range',
        'useCaseCode', 'useCase', 'updatedAt', 'updatedBy'));

    $normalizer->setCircularReferenceHandler(function ($object) {
        return $object->getName();
    });

    $serializer = new Serializer(array($normalizer), array($encoder));
    return $serializer->serialize($this, 'json');
}

Which is very useful because we can choose attributes and we have the entity relations.

In my Twig file :

<div data-tag="{{ tag.serializer }}">...</div>

In JS, I have my Tag Object. Texts are an array of objects. Everything is working great !

Note : Be careful of your Symfony's version. Mine was 3.0.9 and I couldn't install the Serializer Component. I had to update Symfony to 3.2 to make it work.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download