Home > Software design >  How to display results of nested laravel query for api consumption
How to display results of nested laravel query for api consumption

Time:04-13

I have a category model with n-level subcategories. I want to be able to display the list of parent categories on my flutter app. However I'm not sure how to query the db to get this result as a json.

I know that I could access the parent categories and children categories in blade view using the relationship defined in the model below but how to I do that when sending the same data via json to my flutter app?

Finally, I also want to be able to perform an operation such that in the flutter app, when i click on a parent category and it has subcategories, the list of subcategories should be displayed and so up till it's last depth.

My Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $guarded = ['id'];

    public function parent()
    {
        return $this->belongsTo('App\Category', 'parent_id');
    }

    public function children()
    {
        return $this->hasMany('App\Category', 'parent_id');
    }
}

CodePudding user response:

A tree behavior is not an easy task, but luckily I have done it before. I will share some of my code. In your model it should be like this

class CategoryTree extends Model {
    protected $primaryKey = 'category_tree_id';
    protected $table = 'category_tree';
    

    public function children() {
        return $this->hasMany(self::class, 'parent_id', 'category_tree_id');
    }

    public function parent() {
        return $this->hasOne(self::class, 'category_tree_id', 'parent_id');
    }
}

and the magic is lies on the resource. Call the collection back with self::collection.

class CategoryTreeResource extends JsonResource {
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request) {
        $children = $this->has_children ? $this->children : NULL;
        return [
            'category_tree_id'  => $this->category_tree_id,
            'name'              => $this->name,
            'image_url'         => $this->image_url,
            'has_children'      => $this->has_children,
            'parent_id'         => $this->parent_id,
            'country_id'        => $this->country_id,
            'is_active'         => $this->is_active,
            'order'             => $this->order,
            'children'          => !empty($children) ? self::collection($children) : NULL,
        ];
    }
}

as you can see it will recursively call the resource and create the tree for you. This is a basic example, you can change whatever behavior that you want inside it

  • Related