Question

I want to add a custom property to the serialized entity's representation, which takes an existing entity property and formats it in a user friendly way by using an existing service.

I defined a subscriber class and injected the service used for formatting the existing entity property and subscribed to serializer.pre_serialize as follows:

class UserSerializationSubscriber implements EventSubscriberInterface
{
    private $coreTwigExtension;

    private $user;

    public function setCoreTwigExtension(TwigExtension $coreTwigExtension)
    {
        $this->coreTwigExtension = $coreTwigExtension;
    }

    public function setUserService(UserService $user)
    {
        $this->user = $user;
    }

    public static function getSubscribedEvents()
    {
        return array(
            array(
                'event' => 'serializer.pre_serialize', 
                'method' => 'onObjPreSerialize', 
                'class' => 'Some\Bundle\Entity\EntityClass',
                'format' => 'json'
            )
        );
    }

    public function onObjPreSerialize(PreSerializeEvent $event)
    {
        $context = $event->getContext();
        $context->attributes->get('groups')->map(
            function(array $groups) use ($event) {
                if (in_array('somegroup', $groups)) {
                    $obj= $event->getObject();

                    if ($obj->getConfirmedOn()) {
                         $contextualDate = $this->coreTwigExtension->getContextualDate($obj->getConfirmedOn());
                         $event->getVisitor()->addData('displayConfirmedOn', $contextualDate);
                    }
                }
            }
        );
    }

}

Subscriber registration:

some_bundle.handler.serialization:
    class: Some\Bundle\Handler\ObjectSerializationSubscriber
    calls:
        - [setCoreTwigExtension, ['@bundle_core.twig.extension']]
        - [setUserService, ['@some_bundle.service.user']]
    tags:
        - { name: jms_serializer.event_subscriber }

When I serialize an array/collection of entity Some\Bundle\Entity\EntityClass I get the following error:

There is already data for "displayConfirmedOn".

How do I resolve this? The only thing stopping me from using @VirtualProperty in the entity is that the virtual property output depends on a service, and no dependencies should be injected into an entity.

Was it helpful?

Solution

The error is due to the fact that the entity itself already exposes an attribute displayConfirmedOn for serialization. When your event listener runs it is not allowed to add an attribute with the same name to the output and you get this error.

Simply stop exposing the attribute in your entity and then the listener can add a property of the same name.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top