core: Removals from an ArrayCollection gets normalized wrong
Hi,
I just noticed that if one removes an element from a collection, the result is wrong.
Example
/**
* @ORM\Entity
*/
class Project
{
/**
* @ORM\OneToMany(targetEntity="PartKeepr\ProjectBundle\Entity\ProjectPart",mappedBy="project",cascade={"persist", "remove"})
* @Groups({"default"})
* @var ArrayCollection
*/
private $parts;
public function __construct () {
$this->parts = new ArrayCollection();
}
/**
* Returns the parts array
*
* @return ProjectPart[] An array of ProjectPart objects
*/
public function getParts()
{
return $this->parts;
}
/**
* Adds a Project Part
*
* @param ProjectPart $projectPart An attachment to add
*/
public function addPart($projectPart)
{
$projectPart->setProject($this);
$this->parts->add($projectPart);
}
/**
* Removes a Project Part
*
* @param ProjectPart $projectPart An attachment to remove
*/
public function removePart($projectPart)
{
$projectPart->setProject(null);
$this->parts->removeElement($projectPart);
}
}
Note that the example class is barebones and doesn’t include e.g. an identifier, which is actually the case in my project.
When I remove any part except the first, the resulting JSON has array indexes in the result:
{
"@context":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/contexts\/Project",
"@id":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/projects\/25",
"@type":"Project",
"parts":{
"0":{ # This index is included which is otherwise missing
"@id":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/project_parts\/758",
"@type":"ProjectPart",
"part":{
"@id":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/parts\/284",
"@type":"Part",
}
}
I would expect the resulting JSON like this:
{
"@context":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/contexts\/Project",
"@id":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/projects\/25",
"@type":"Project",
"parts":{
{ # No index
"@id":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/project_parts\/758",
"@type":"ProjectPart",
"part":{
"@id":"\/~felicitus\/PartKeepr\/web\/app_dev.php\/api\/parts\/284",
"@type":"Part",
}
}
If my adder/remover implementation is wrong, please let me know. If so, I must refer to https://github.com/dunglas/DunglasApiBundle/issues/153#issuecomment-119265974 again (Sample Implementation of getters/adders/removers)
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 44 (32 by maintainers)
Hi all ! In ApiPlatform\Core\Serializer\AbstractItemNormalizer :
Returning a non-indexed array solves the problem :
$value[] = $this->normalizeRelation($propertyMetadata, $obj, $resourceClass, $format, $context);Is there a case we want to keep the indexes in a to-many relations collection ?
@felicitus I’ve already encountered the problem and unfortunately there is not much solutions as PHP doesn’t have explicit hash map data structures.
When using
ArrayCollectionyou can use the::toArray():I was thinking about patching doctrine (provide a
reorderconstructor flag in for Doctrine Collection implementations for instance).