sgtpepper's avatar

Paged Resource Collection not working

I'm building an API and I want to use Laravel's API Resources, but I'm facing a bit of a problem with pagination.

As I understand from the docs https://laravel.com/docs/5.5/eloquent-resources if I pass an instance of Illuminate\Pagination\LengthAwarePaginator to a Resource Collection or even a Resource trough the collection method it should build the paginator in a JSON format. Well the problem is it isn't and I'm not sure why. Here is a sample of the code I'm using

ClientCollection.php

    public function toArray($request)
        {
            return parent::toArray($request);
        }

ClientController.php

    public function index()
    {
        $clients = Client::paginate(15);

        return response(new ClientCollection($clients));
    }   

And the JSON response is simply

[
    {
        "name": "John Doe",
        "email": "[email protected]"
    },
    {
        "name":"Jane Doe",
        "email": "[email protected]"
    },
    ...
]

So there is no really any pagination taking place at the moment. Hope someone can guide me to the right way

Thank you

0 likes
12 replies
bobbybouwmann's avatar

So I'm not sure, but I think you need to wrap your data in an array to actually make the pagination work. The thing is that it will add extra meta data for pagination and therefore it should be in it's own wrapper

// ClientCollection.php

public function toArray($request)
{
    return [
        'data' => parent::toArray($request),
    ];
}

You can enable withoutWrapping as well, but with pagination that doesn't work because you always have the extra meta data!

Let me know if this works for you!

Snapey's avatar

you also need to say how many records in each page, eg ->paginate(2)

sgtpepper's avatar

I forgot to put it on the code sample but I paginate the results 15 items per page that seems to have no effect whatsoever. I also tried wrapping the collection on the data key and it gets returned inside that key in the JSON response but the links and meta keys are still missing

Snapey's avatar

Perhaps not related, but what does this do ?

    public function toArray($request)
        {
            return parent::toArray($request);
        }
sgtpepper's avatar

Hi, Snapey. The mehtod simply calls the toArray method on the App\Client model that is it returns all the fields the model have as they are structured in the database. And yes I've read the pagination documentation, as you can see you can return the paginator as a response and it would be converted to JSON the problem is that is not the format I want with the links in a links key and the meta data in the meta key but I guess I could do that work in the Resource if that's the only way Thank you for replying

sgtpepper's avatar
sgtpepper
OP
Best Answer
Level 9

I've found the solution. Turns out the problem was that I was returning the collection with the response helper and I'm not sure why but that removes all the structure the resource give to the data. So to solve it simply return the collection from the controller like so


    public function index()
        {
            $clients = Client::paginate(15);

            return new ClientCollection($clients);
        } 

16 likes
shadrix's avatar

@sgtpepper THANK YOU. I was looking for answers but could not find it. Indeed you cannot use response()->json()

slev1n's avatar

You can customize your pagination instead

ClientCollection.php

public function toArray()
{
    'count' => $this->count(),
    'total' => $this->total(),
    'prev'  => $this->previousPageUrl(),
    'next'  => $this->nextPageUrl(),

    'result' => $this->collection
}

See https://laravel.com/docs/5.8/pagination#paginator-instance-methods

ClientController.php

public function index()
{
        $clients = Client::paginate(15);

        return response(new ClientCollection($clients));
} 
4 likes
YanBess's avatar

Just replace extending of ResourceCollection to JsonResource and you will get all pagination data using response()

aakashdesai-pro's avatar

Meta data is not coming, When i loading child resources using load() method. Any one can tell me why this issue is happening?

Please or to participate in this conversation.