Search code examples
javascriptphparraysjsontwig

My selector options are undefined but the selector length is good


I send to my twig page an array composed of 3 objects (my unit tests are valid, my objects are not null here):

echo $this->twig->render('form/index.html.twig', ['verbalAggressions' => $verbal_aggressions]);

Then I get :

const verbalAggressions = {{ verbalAggressions|json_encode }};

My variable is composed of 3 objects, but they are undefined :

enter image description here

I use version 3.4.3 of twig, maybe I should upgrade?

My properties of model :

<?php

namespace app\models;

use app\database\Database;

/**
 * The aggressions
 */
class Aggression
{
    /**
     * @var int
     */
    private int $id;
    /**
     * @var string
     */
    private string $name;
    /**
     * @var string
     */
    private string $type;

    /**
     * @param int $id
     * @param string $name
     * @param string $type
     */
    public function __construct(int $id, string $name, string $type)
    {
        $this->id = $id;
        $this->name = $name;
        $this->type = $type;
    }

My getters :

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

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return $this->type;
    }

My method to get verbal aggressions :

public static function getVerbalAggressions(): array|null
    {
        $aggressions = Aggression::findAll();
        if ($aggressions != null) {
            $verbalAggressions = [];
            foreach ($aggressions as $verbalAggression) {
                if ($verbalAggression instanceof Aggression) {
                    if ($verbalAggression->getType() == 'Verbale' || $verbalAggression->getType() == 'Commun') {
                        $verbalAggressions[] = $verbalAggression;
                    }
                }
            }
            return $verbalAggressions;
        } else {
            return null;
        }
    }

Solution

  • The properties in your object are private, which means that they will be ignored when you json encode the object.

    If you want to keep those properties private, you can use the JsonSerializable-interface to decide what you want the object to use when it's being serialized as json.

    1. Let Aggression implement the interface:
    use JsonSerializable;
    
    class Aggression implements JsonSerializable
    {
    
    1. Add the required method to the class:
    /**
     * Return the data that should be json serialized
     * 
     * @return mixed
     */
    public function jsonSerialize(): mixed
    {
        // Here you can return an array with all the properties you want in your json
        return [
            'id' => $this->getId(),
            'name' => $this->getName(),
            'type' => $this->getType(),
        ];
    }
    

    If you now pass the object to json_encode(), PHP will use the response of the objects jsonSerialize()-method.

    Demo: https://3v4l.org/KueIs