Kyle Corbin Hurst
Kyle Corbin Hurst

Reputation: 1121

How do I structure data in a resource collection?

I'm trying to structure the data output of a resource collection. With pagination I'm getting:

Undefined property: Illuminate\Pagination\LengthAwarePaginator::$id

With return new PostCollection(Post::latest()->get()); as seen in the PostControllers index I'm getting:

Property [id] does not exist on this collection instance.

PostController

public function index()
{
    //return PostResource::collection(Post::latest()->paginate(1));

    return new PostCollection(Post::latest()->paginate(1));
}

PostCollection Resource

class PostCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        //return parent::toArray($request);

        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => $this->content,
            'slug' => $this->slug,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,  
        ];
    }

}

The commented out PostResource::collection() works perfectly fine with the same code. How do I structure the data of my PostCollection resource?

Upvotes: 0

Views: 225

Answers (1)

Kyle Corbin Hurst
Kyle Corbin Hurst

Reputation: 1121

The $this->collection property of a resource collection is automatically populated with the result of mapping each item of the collection to its singular resource class. The singular resource class is assumed to be the collection's class name without the trailing Collection string.

In easier terms the PostCollection inherits the structure from a singular resource called Post. Since my post resource is named PostResource, I need to add a $collects property with the path of my PostResource like so:

class PostCollection extends ResourceCollection
{
    /**
     * The resource that this resource collects.
     *
     * @var string
     */
    public $collects = 'App\Http\Resources\PostResource';

    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {

        return [
            'data' => $this->collection,
        ];
    }

}

I googled how to do this a few times, and I must of scanned over this in the docs a few times not seeing how to do this. Hope this helps.

Upvotes: 0

Related Questions