Laravel with GraphQL, returning an nested array
I am using this package for my Laravel 5.5 installation and it is working flawless except for one small thing.
In my website we use an nested array to build our home menu. This means that we have a "main category" which can contain an "subcategory". In return, this "subcategory" can have a "subcategory" her self and thus we are able to nest menu options as deep as we want using a LEFT and RIGHT system.
What I am doing now:
I retrieve all my menu items and in PHP I build a correct array so I can display it easily in my front-end (in my case Angular 4). What PHP returns to GraphQL is this code (example code):
Array (
[0] => stdClass Object (
[id] => 1
[category_name] => sdgsdgsdgg
[clean_category_name] => sdgsdgsdgg
[depth] => 0
[post_count] => 1
[children] => Array
(
)
)
[1] => stdClass Object (
[id] => 2
[category_name] => fsdffsdf
[clean_category_name] => fsdffsdf
[depth] => 0
[post_count] => 0
[children] => Array
(
[0] => stdClass Object
(
[id] => 3
[category_name] => xxxx
[clean_category_name] => xxxx
[depth] => 1
[post_count] => 0
[children] => Array
(
)
)
)
)
)
The problem we have now is that the output of GraphiQL / GraphQL is different. It removes the "nested" fields. Example here:
{
"data": {
"categories": [
{
"id": 1,
"category_name": "sdgsdgsdgg",
"clean_category_name": "sdgsdgsdgg"
},
{
"id": 2,
"category_name": "fsdffsdf",
"clean_category_name": "fsdffsdf"
}
]
}
}
Meaning we are losing all nested menu options in our front-end.
We tried finding a solution in the GraphQL manual but quite frankly, we are unable to understand how to fix this, so that it will display / return multi dimensional arrays.
I hope someone can explain to us what we need to do, or give us a small example.
I will show you my GraphQL code below ;)
Best regards
CategoryQuery.php
namespace App\GraphQL\Query;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Query;
use Modules\Kennisbank\Categories;
class CategoryQuery extends Query
{
protected $attributes = [
'name' => 'categories'
];
public function type()
{
return Type::listOf(GraphQL::type('Category'));
}
public function args()
{
return [
'id' => ['name' => 'id', 'type' => Type::string()]
];
}
// execute the query and return the data
public function resolve($root, $args)
{
$categories = getCategories();
$lastDepth = 0;
$res = [];
$tempParent = [];
for($i = count($categories) - 1; $i >= 0; $i--) {
$item = &$categories[$i];
$item->children = [];
if($item->depth < $lastDepth)
{
$item->children = $tempParent;
$tempParent = [];
}
if($item->depth > 0)
$tempParent[] = $item;
if($item->depth == 0)
$res[] = $item;
$lastDepth = $item->depth;
}
$res = $this->reverse_tree_children_array($res);
return $res;
}
private function reverse_tree_children_array($arr)
{
foreach ($arr as $key => $val)
{
if (count($val->children) > 0)
$arr[$key]->children = $this->reverse_tree_children_array($val->children);
}
return array_reverse($arr);
}
}
CategoryType.php
namespace App\GraphQL\Type;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;
class CategoryType extends GraphQLType
{
protected $attributes = [
'name' => 'Category',
'description' => ''
];
protected $inputObject = false;
public function fields() {
return [
'id' => [
'type' => Type::int(),
'description' => 'The id of the FAQ'
],
'category_name' => [
'type' => Type::string(),
'description' => ''
],
'clean_category_name' => [
'type' => Type::string(),
'description' => ''
]
];
}
}
I updated my CategoryType which seems to give me a little bit of progress, but now I am stuck on a "Expected iterable, but did not find one for field Category.children" error :(
return [
'id' => [
'type' => Type::int(),
'description' => 'The id of the FAQ'
],
'category_name' => [
'type' => Type::string(),
'description' => ''
],
'clean_category_name' => [
'type' => Type::string(),
'description' => ''
],
'children' => [
'type' => Type::listOf( GraphQL::type('Category') ), // This is saying that children is a "list" of the type "Category"
'description' => 'Child of this maincategory', // A short description about what "children" is going to provide
'resolve' => function($data, $args) { // The data that we want to return, for now just gibberish
return 'return_meh';
}
]
];
} ```
Please or to participate in this conversation.