I get JSON from API, and I need to convert it to a recursively nested object.
One property of my object is an array with elements of the same type as the parent object.
Here is my Data class:
class Group extends Data
{
/** @var \App\Data\Group[] **/
public array $subGroups;
public function __construct(
public string $id,
array $subGroups,
) {
/** @var \App\Data\Group[] */
$this->subGroups = collect($subGroups)
->map(fn (array $group) => Group::from($group))
->all();
}
}
And here is my JSON response:
[
{
"id": "1",
"subGroups": [
{
"id": "1-1",
"subGroups": []
},
{
"id": "1-2",
"subGroups": [
{
"id": "1-2-1",
"subGroups": []
}
]
}
]
},
{
"id": "2",
"subGroups": []
}
]
Having the following methods:
/**
* @param array[] $groups
* @return Group[]
*/
public function toGroups(array $groups): array
{
return collect($groups)
->map(fn (array $group) => Group::from($group))
->all();
}
/**
* @return Group[]
*/
public function toGroupsFromResponse(ResponseInterface $response): array
{
return $this->toGroups(
json_decode($response->getBody()->getContents(), true)
);
}
I wanted for toGroupsFromResponse
to return and object with nested Group type objects like so
# Pseudo-code
[
Group {
string id = '1'
Group[] subGroups = [
Group {
string id = '1-1'
Group[] subGroups = []
},
Group {
string id = '1-2'
Group[] subGroups = [
Group {
string id = '1-2-1'
Group[] subGroups = []
},
]
}
]
},
Group {
string id = '2'
Group[] subGroups = []
}
]
Instead, all subGroups are arrays of array.
# Pseudo-code
[
Group {
string id = '1'
array subGroups = [
array {
string id = '1-1'
array subGroups = []
},
array {
string id = '1-2'
array subGroups = [
array [
string id = '1-2-1',
array subGroups = []
],
]
}
]
},
Group {
string id = '2'
array subGroups = []
}
]
It worked when I used Spatie's old DataTransferObject object, but I had trouble using the new Data object.
A broad question, I know, but where have I gone wrong?