Search code examples
phpsymfonyserializationsymfony-3.2

Normalizer null reference using NormalizerAwareTrait


I have two objects with a Parent-Child relationship. For each object I have a custom normalizer as can be seen below:

ChildNormalizer.php

use Symfony\Component\Serializer\Normalizer\scalar;

class ChildNormalizer
{  
    public function normalize($object, $format = null, array $context = array())
    {
      return [
        "name" => $object->getName(),
        "age" => $object->getAge(),
        ...
        ];
    }

    public function supportsNormalization($data, $format = null)
    {
        return ($data instanceof Child) && is_object($data);
    }
}

ParentNormalizer.php

use Symfony\Component\Serializer\Encoder\NormalizationAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\scalar;

class ParentNormalizer implements NormalizerInterface, NormalizationAwareInterface
{
    use NormalizerAwareTrait;

    public function normalize($object, $format = null, array $context = array())
    {
      return [
        ...
        "children" => array_map(
            function ($child) use ($format, $context) {
                return $this->normalizer->normalize($child);
            }, $object->getChildren()
          ),
        ...
        ];
    }

    public function supportsNormalization($data, $format = null)
    {
        return ($data instanceof Parent) && is_object($data);
    }
}

When I try to serialize the Parent object which in turn normalizes the Child object I get the following exception:

Call to a member function normalize() on null

Have I missed a configuration step, or what the hell am I doing wrong?


Solution

  • Solved the issue, I was implementing the wrong *AwareInterface.

    The code works perfectly if the ParentNormalizer implements NormalizerAwareInterface rather than NormalizationAwareInterface.

    use Symfony\Component\Serializer\Encoder\NormalizerAwareInterface;
    use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
    use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
    use Symfony\Component\Serializer\Normalizer\scalar;
    
    class ParentNormalizer implements NormalizerInterface, NormalizerAwareInterface
    {
        ...
    }