<p>Element API doesn’t have any special support for returning nested arrays of element data, but you can hack it by limiting the initial batch of categories to just those at the top level, and within the transformer function, running additional queries to fetch nested elements, and incorporating them into the parent category’s return data.</p>

<p>To limit the initial batch to just the ones at the top level, change your <code>criteria</code> value to:</p>



<pre class="lang-php prettyprint-override"><code>'criteria' =&gt; ['group' =&gt; $slug, 'level' =&gt; 1],
</code></pre>

<p>And then update your <code>transform()</code> method to this:</p>

<pre class="lang-php prettyprint-override"><code>public function transform(CategoryModel $category)
{
    $data = [
        'id' =&gt; $category-&gt;id,
        'uri' =&gt; $category-&gt;uri,
        'title' =&gt; $category-&gt;title,
    ];

    $children = $category-&gt;getChildren();

    if ($children) {
        $data['children'] = [];

        foreach ($children as $child) {
            $data['children'][] = $this-&gt;transform($child);
        }
    }

    return $data;
}
</code></pre>

<p>The caveat here is that this will require an additional SQL query for each individual category, since we need to check each category to see if it has any children. As of <a href="https://craftcms.com/changelog#build2789" rel="nofollow">Craft 2.6.2789</a> you can fix that by <a href="https://craftcms.com/docs/templating/eager-loading-elements" rel="nofollow">eager-loading</a> the categories’ children with the newly-supported <code>children</code> keyword.</p>

<p>To do that, update your <code>criteria</code> value with this:</p>

<pre class="lang-php prettyprint-override"><code>'criteria' =&gt; [
    'group' =&gt; $slug,
    'level' =&gt; 1,
    'with' =&gt; ['children.children.children']
],
</code></pre>

<p>(Put as many <code>.children</code> as the number of levels the category group will have. So if it’s limited to two levels, <code>children.children</code> would suffice.)</p>

CC BY-SA 3.0
2017-12-14T23:53:52.867Z
Tried adding this ``` 'with' => ['children.children.children']``` and it didn't seem to have any impact. I'm on 2.6.3000. Does this work with single entry endpoints?
user814584
CC BY-SA 3.0
2018-01-20T23:15:56.320Z
@user814584 Not sure i’m following you - probably worth posting a new question with a complete code example.
Brandon Kelly
CC BY-SA 3.0
2016-05-25T22:49:43.153Z
2016-05-26T12:07:23.013Z
2016-05-26T12:07:23.013Z
Brandon Kelly
<p>Currently involved with handling the CategoryModel and using this code</p>

<pre><code>return [
    'endpoints' =&gt; [
        // Category    
    'category/&lt;slug:{slug}&gt;.json' =&gt; function($slug) {
        require craft()-&gt;path-&gt;getConfigPath().'controllers/CategoryTransformer.php';
        return [
            'elementType' =&gt; 'Category',
            'criteria' =&gt; ['group' =&gt; $slug],
            'transformer' =&gt; new CategoryTransformer(),
        ];
    },
];
</code></pre>

<p>refering to CategoryTransformer.php</p>

<pre><code>class CategoryTransformer extends CategoryFieldTransformer
{
    var $entry, $typeMedia;
    public function transform(CategoryModel $entry)
    {
        echo $entry['uri']."
        ";
        $child = $entry-&gt;getChildren();
    }
}
</code></pre>

<p>It works all though I am not having success with been able to build a hierarchical object that would have parent and child nodes for the API to return.
I made a modest attempt at building the categories in another area of the API interface but did not return what I was hoping for.</p>

<pre><code> public function type_categories($mixedArray){
    $categories = array();
    foreach($mixedArray as $rkey =&gt; $rvalue){
        $level = $mixedArray[$rkey]-&gt;level - 1;
        $argt = array(
            'id' =&gt; $mixedArray[$rkey]-&gt;id,
            'uri' =&gt; $mixedArray[$rkey]-&gt;uri,
            'title' =&gt; $mixedArray[$rkey]-&gt;title,
            'level' =&gt; $mixedArray[$rkey]-&gt;level,
            'slug' =&gt; $mixedArray[$rkey]-&gt;slug,
            'groupId' =&gt; $mixedArray[$rkey]-&gt;groupId,
            'level' =&gt; $mixedArray[$rkey]-&gt;level
            );
        // Children
        $obg = $mixedArray[$rkey]-&gt;children;
        $kids = array();
        foreach($obg as $kid =&gt; $kidval){
          $kids[] = array(
            'id' =&gt; $obg[$kid]-&gt;id,
            'uri' =&gt; $obg[$kid]-&gt;uri,
            'title' =&gt; $obg[$kid]-&gt;title,
            'level' =&gt; $obg[$kid]-&gt;level,
            'slug' =&gt; $obg[$kid]-&gt;slug,
            'groupId' =&gt; $obg[$kid]-&gt;groupId,
            'level' =&gt; $obg[$kid]-&gt;level
            );
        } 
        $argt['children'] = $kids;                                                                    
        $categories[$level][] = $argt;                                        
    }
    return $categories;
}
</code></pre>

<p>I as well took a peek at CategoriesController.php in the core and couldn't find anything that could assist me. It ends with Twig handling the object.</p>

<p>Is it possible if anyone has done something similar that I may reference to build a clean object which is intuitive for someone to loop on in JSON format?</p>

<p>Following is an example of the intended hierarchy:</p>

<pre><code>stdClass Object
(
[0] =&gt; Array
    (
        [id] =&gt; 1
        [uri] =&gt; cars
        [title] =&gt; Cars
        [children] =&gt; Array
            (
                [0] =&gt; Array
                    (
                        [id] =&gt; 4
                        [uri] =&gt; bmw
                        [title] =&gt; BMW
                    )

                [1] =&gt; Array
                    (
                        [id] =&gt; 6
                        [uri] =&gt; audi
                        [title] =&gt; Audi
                    )

                [2] =&gt; Array
                    (
                        [id] =&gt; 7
                        [uri] =&gt; vw
                        [title] =&gt; VW
                        [children] =&gt; Array
                            (
                                [0] =&gt; Array
                                    (
                                        [id] =&gt; 50
                                        [uri] =&gt; hatchback
                                        [title] =&gt; Hatchback
                                    )

                                [1] =&gt; Array
                                    (
                                        [id] =&gt; 50
                                        [uri] =&gt; sedan
                                        [title] =&gt; Sedan
                                    )

                            )

                    )

            )

    )

[1] =&gt; Array
    (
        [id] =&gt; 1
        [uri] =&gt; trucks
        [title] =&gt; trucks
    )
)
</code></pre>

<p>Thanks</p>

CC BY-SA 3.0
2016-05-25T17:35:53.900Z
What do you mean by "hierarchical object"? Can you update your question with an example of what you're hoping the resulting JSON will look like?
Brandon Kelly
<categories><plugin-elementapi>
ElementAPI handling CategoryModel and returning a heirachical object
# ElementAPI handling CategoryModel and returning a heirachical object

(Asked by: username_0 on 2016-05-25)

Currently involved with handling the CategoryModel and using this code
return [
    'endpoints' => [
        // Category    
    'category/.json' => function($slug) {
        require craft()->path->getConfigPath().'controllers/CategoryTransformer.php';
        return [
            'elementType' => 'Category',
            'criteria' => ['group' => $slug],
            'transformer' => new CategoryTransformer(),
        ];
    },
];

refering to CategoryTransformer.php
class CategoryTransformer extends CategoryFieldTransformer
{
    var $entry, $typeMedia;
    public function transform(CategoryModel $entry)
    {
        echo $entry['uri']."
        ";
        $child = $entry->getChildren();
    }
}

It works all though I am not having success with been able to build a hierarchical object that would have parent and child nodes for the API to return.
I made a modest attempt at building the categories in another area of the API interface but did not return what I was hoping for.
 public function type_categories($mixedArray){
    $categories = array();
    foreach($mixedArray as $rkey => $rvalue){
        $level = $mixedArray[$rkey]->level - 1;
        $argt = array(
            'id' => $mixedArray[$rkey]->id,
            'uri' => $mixedArray[$rkey]->uri,
            'title' => $mixedArray[$rkey]->title,
            'level' => $mixedArray[$rkey]->level,
            'slug' => $mixedArray[$rkey]->slug,
            'groupId' => $mixedArray[$rkey]->groupId,
            'level' => $mixedArray[$rkey]->level
            );
        // Children
        $obg = $mixedArray[$rkey]->children;
        $kids = array();
        foreach($obg as $kid => $kidval){
          $kids[] = array(
            'id' => $obg[$kid]->id,
            'uri' => $obg[$kid]->uri,
            'title' => $obg[$kid]->title,
            'level' => $obg[$kid]->level,
            'slug' => $obg[$kid]->slug,
            'groupId' => $obg[$kid]->groupId,
            'level' => $obg[$kid]->level
            );
        } 
        $argt['children'] = $kids;                                                                    
        $categories[$level][] = $argt;                                        
    }
    return $categories;
}

I as well took a peek at CategoriesController.php in the core and couldn't find anything that could assist me. It ends with Twig handling the object.
Is it possible if anyone has done something similar that I may reference to build a clean object which is intuitive for someone to loop on in JSON format?
Following is an example of the intended hierarchy:
stdClass Object
(
[0] => Array
    (
        [id] => 1
        [uri] => cars
        [title] => Cars
        [children] => Array
            (
                [0] => Array
                    (
                        [id] => 4
                        [uri] => bmw
                        [title] => BMW
                    )

                [1] => Array
                    (
                        [id] => 6
                        [uri] => audi
                        [title] => Audi
                    )

                [2] => Array
                    (
                        [id] => 7
                        [uri] => vw
                        [title] => VW
                        [children] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 50
                                        [uri] => hatchback
                                        [title] => Hatchback
                                    )

                                [1] => Array
                                    (
                                        [id] => 50
                                        [uri] => sedan
                                        [title] => Sedan
                                    )

                            )

                    )

            )

    )

[1] => Array
    (
        [id] => 1
        [uri] => trucks
        [title] => trucks
    )
)

Thanks

**Tags:** categories, plugin-elementapi

> **Comments:**
> **username_1**: What do you mean by "hierarchical object"? Can you update your question with an example of what you're hoping the resulting JSON will look like?  

---

## 1 answers

### Answer by username_1 on 2016-05-25. Score: 3 | Accepted answer

Element API doesn’t have any special support for returning nested arrays of element data, but you can hack it by limiting the initial batch of categories to just those at the top level, and within the transformer function, running additional queries to fetch nested elements, and incorporating them into the parent category’s return data.
To limit the initial batch to just the ones at the top level, change your criteria value to:
'criteria' => ['group' => $slug, 'level' => 1],

And then update your transform() method to this:
public function transform(CategoryModel $category)
{
    $data = [
        'id' => $category->id,
        'uri' => $category->uri,
        'title' => $category->title,
    ];

    $children = $category->getChildren();

    if ($children) {
        $data['children'] = [];

        foreach ($children as $child) {
            $data['children'][] = $this->transform($child);
        }
    }

    return $data;
}

The caveat here is that this will require an additional SQL query for each individual category, since we need to check each category to see if it has any children. As of Craft 2.6.2789 you can fix that by eager-loading the categories’ children with the newly-supported children keyword.
To do that, update your criteria value with this:
'criteria' => [
    'group' => $slug,
    'level' => 1,
    'with' => ['children.children.children']
],

(Put as many .children as the number of levels the category group will have. So if it’s limited to two levels, children.children would suffice.)

> **Comments:**
> **username_2**: Tried adding this ``` 'with' => ['children.children.children']``` and it didn't seem to have any impact. I'm on 2.6.3000. Does this work with single entry endpoints?  
> **username_1**: @username_2 Not sure i’m following you - probably worth posting a new question with a complete code example.  

---

