JMS Serialize ArrayCollection as an object

3.9k views Asked by At

I'am using the JMS Serializer. The JsonSerializer gives me an incorrect array format when it works with Doctrine ArrayCollection types. The spected results should follow the format [ {}, {} ] but it gives me { 1: {}, 2: {} }.

Additional information about this scenario. It only occurs when I try to serialize an object that contains an object that contains the ArrayCollection and the ArrayCollection includes the first level object. For example:

{  
   "description":"Text provided",
   "date":"1434145921000",
   "oid":1,
   "userCreator":{  
      "username":"name123",
      "password":"psw",
      "oid":2,
      "name":"the-name",
      "lastname":"the-lasname",
      "announcements":{  
         "1":{  
            "description":"Clases de inglés",
            "date":"1434745921000",
            "oid":3
         },
         "2":{  
            "description":"Reparar ordenador",
            "date":"1434145921000",
            "oid":5
         }
      }
   }
}

However that not occurs if I serialize the user entity directly:

{  
   "username":"user1",
   "password":"123",
   "oid":2,
   "name":"Rafael",
   "lastname":"Jimenez"
   "announcements":[  
      {  
         "description":"Cargar cajas a la guardilla",
         "date":"1434145921000",
         "oid":1
      },
      {  
         "description":"Contar césped y quitar malas hierbas",
         "date":"1434745921000",
         "oid":3
      },
      {  
         "description":"Reparar ordenador",
         "date":"1434145921000",
         "oid":5
      }
   ]
}

Any clue?

2

There are 2 answers

0
tom10271 On

I think the serializer will check to see if the array is a numeric array or not and decide serializing it to JS Array or Object.

If there is a cell inside a array is null, it will first skip that cell, skipping it makes indexes discontinue and serializer will recognize it as associative array.

array:28 [
  0 => "High Fashion"
  1 => "Contemporary"
  2 => "Streetwear"
  3 => null
  4 => "Grooming"
]

Since $arr[3] is null, it skips. Once skipped, index discontinued. => Serializer consider it as a associative array.

Solution for this case:

First remove empty cell then get the array values and serialize array_values(array_filter($resources))

3
vl.lapikov On

You need to reset keys in ArrayCollection array:

$associative = new ArrayCollection([0 => 1, 2 => 1]);
$list = new ArrayCollection($associative->getValues());

As @stof sad on github:

If your array is not indexed with a sequence from 0 to count($array) - 1, getting an JS object rather than an array is the expected behaviour, because this is how associative arrays need to be converted to JSON. And if keys are not such sequence, your array is a map, not a list.

Take a look to examples:

php > echo json_encode([0 => 1, 1 => 1]);
[1,1]
php > echo json_encode([0 => 1, 2 => 1]);
{"0":1,"2":1}