Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JMS Serialize ArrayCollection as an object

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?

like image 725
Rafa0809 Avatar asked Jun 13 '15 17:06

Rafa0809


2 Answers

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}
like image 142
vl.lapikov Avatar answered Nov 15 '22 09:11

vl.lapikov


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))

like image 26
tom10271 Avatar answered Nov 15 '22 10:11

tom10271