JMS Serialize ArrayCollection as an object
Asked Answered
T

2

6

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?

Toniatonic answered 13/6, 2015 at 17:43 Comment(0)
T
4

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}
Tricuspid answered 31/3, 2016 at 16:19 Comment(3)
The entities are associated using the Doctrine ArrayCollection. So that serialize this kind of objects is very common (in my opinion). In addition, ArrayCollection sound like "array" more than like "associative array". May you could consider other approach for this kind of serialization.Toniatonic
Thanks! Got it. Your example is in a simple scenario. Imagine what happens when you have an array collection contained into more array collections recursively. I could code a module for that, but the library should deal with this issue to support a basic type as array collection. Do you agree?Toniatonic
It depends how you get associative arrays. In your example "announcements" missing zero index. Was it filtered or got deleted? If so you can apply reseting of keys right after filtering of an array. If you have recursive filtering, then you need to apply reseting keys recursively based on your filtering algorithm. On the other hand you may try to recursively go through resulted javascript object and cast it to list. It depends on what exactly you trying to do.Tricuspid
H
1

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

Hinduism answered 13/5, 2016 at 2:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.