Amir Ur Rehman
Amir Ur Rehman

Reputation: 670

How to get pagination links in resource collection - Laravel 5.7.19

I am working with laravel API resource. when we don't use any resource collection we get pagination links etc with paginate(10). but when i use Resource::collection i get nothing, just the fields i put in resource.

This is my Controller

return response()->json([
  "items" => LatestProjectsResource::collection(Project::has('pages')->where('type', $type)->latest()->paginate(20))
]);

And this is my Resource

public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->name,
            'slug' => $this->slug,
            'url' => $this->url,
            'thumbnail' => new ThumbnailResource($this->thumbnail),
        ];
    }

Result

enter image description here

I tried some answers from online community including this Customising Laravel 5.5 Api Resource Collection pagination one but its not working

I tried $this->collection but no luck

Please help me out here.

Upvotes: 2

Views: 5649

Answers (2)

Alaa Moneam
Alaa Moneam

Reputation: 527

To make your code clean make a PaginationResource to be used across different collections and make single place for editing pagination details

then inside any resource add your Pagination resource as follow

this is Pagination resource

public function toArray($request) : Array
    {
        return [
            'total' => $this->total(),
            'count' => $this->count(),
            'per_page' => $this->perPage(),
            'current_page' => $this->currentPage(),
            'total_pages' => $this->lastPage()
        ];
    }

and add it to any other collection like this

 public function toArray($request) : Array
    {
        $pagination = new PaginationResource($this);

        return [
            'templates' => $this->collection,
            $pagination::$wrap => $pagination,
        ];
    }

Upvotes: 0

Hkan
Hkan

Reputation: 3383

I've solved this issue by overriding a regular resource class's collection method.

public static function collection($data)
{
    /* is_a() makes sure that you don't just match AbstractPaginator
     * instances but also match anything that extends that class.
     */
    if (is_a($data, \Illuminate\Pagination\AbstractPaginator::class)) {
        $data->setCollection(
            $data->getCollection()->map(function ($listing) {
                return new static($listing);
            })
        );

        return $data;
    }

    return parent::collection($data);
}

This simply checks if the given data is and instance of Laravel's paginator classes and if it is, it just modifies the underlying collection and returns the same paginator instance. You can put this in an abstract collection class or in every resource class.

Upvotes: 2

Related Questions