Symfony Array passed from Twig to JS is always empty

Viewed 32

im trying to pass variables from Twig to a JS File to work with them. No matter what I do the console log is always an empty array. But that array is not empty as the dump shows. What am I doing wrong?

PHP:

$user = $this->getUser();

$markers = $doctrine->getRepository(Marker::class)->findBy(["relatedUser" => $user]);

return $this->render("map/index.html.twig", [
            "controller_name" => "MapController",
            "title" => "Map",
            "markers" => $markers
        ]);

HTML:

{% block javascripts %}
    <script>
        var markers = '{{ markers|json_encode }}';
    </script>
    {{ encore_entry_script_tags('mapLogic') }}
{% endblock %}

Javascript:

document.addEventListener('DOMContentLoaded', () => {
    console.log(JSON.parse(window.markers));
});

Web Console:

enter image description here

Dump:

enter image description here

Here is the entire code from my Marker Entity. But it does not implement JsonSerializabe:

<?php

namespace App\Entity;

use App\Repository\MarkerRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: MarkerRepository::class)]
class Marker
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne(inversedBy: 'markers')]
    #[ORM\JoinColumn(nullable: false)]
    private ?User $relatedUser = null;

    #[ORM\Column]
    private array $geoData = [];

    #[ORM\Column]
    private ?\DateTimeImmutable $createdAt = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getRelatedUser(): ?User
    {
        return $this->relatedUser;
    }

    public function setRelatedUser(?User $relatedUser): self
    {
        $this->relatedUser = $relatedUser;

        return $this;
    }

    public function getGeoData(): array
    {
        return $this->geoData;
    }

    public function setGeoData(array $geoData): self
    {
        $this->geoData = $geoData;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeImmutable $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

1 Answers

All the properties in your Marker entity are set to private, which means that they will be omitted when you encode it using json_encode().

One way of solving it is to set all properties as public in that entity.

If you don't want to do that, there are another (and in my opinion, better) alternative. You can implement the JsonSerializable interface. Then you can decide what to serialize.

// Import the interface to the current namespace
use JsonSerializable;

// Now implement the interface
class Marker implements JsonSerializable
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne(inversedBy: 'markers')]
    #[ORM\JoinColumn(nullable: false)]
    private ?User $relatedUser = null;

    #[ORM\Column]
    private array $geoData = [];

    #[ORM\Column]
    private ?\DateTimeImmutable $createdAt = null;

    // Now we need to implement the method defined in the interface.
    public function jsonSerialize() {
        // All you need to do here is to return the data you want to encode 
        // in the format you want.
        return [
            'id'          => $this->id,
            'relatedUser' => $this->relatedUser,
            'geoData'     => $this->geoData,
            'createdAt'   => $this->createdAt,
        ];
    }    

    // The rest of your object

Now it should return some actual data.

The manual for JsonSerializable: https://www.php.net/manual/en/class.jsonserializable.php

The manual for jsonSerialize(): https://www.php.net/manual/en/jsonserializable.jsonserialize.php

Related