ResourceCollection doesn't include pagination links
Asked Answered
F

4

10

CommentsCollection

class CommentsCollection extends ResourceCollection
{
    public function toArray($request)
    {
        return [
            'data' => $this->collection
        ];
    }
}

CommentsController

public function index()
{
    $post = Post::find(1);
    return ['post'=> $post, 'comments' => new CommentsCollection(Comment::paginate(1))];
}

Response

"comments": {
        "data": [
            {
                "id": 1,
                "content": "First comment",
                "post_id": 6,
                "account_id": 1,
                "created_at": "2018-03-07 02:50:33",
                "updated_at": "2018-03-07 02:50:34"
            }
        ]
    }

This happens when resource with use of ::collection method or even ResourceCollection returned as a part of the array.

If we're going to remove array and return pure collection:

return new CommentsCollection(Comment::paginate(1))

everything is going to work fine and response will include meta and links.

Why does API Resource (using collection method or ResourceCollection) doesn't include pagination information when returned in array?

Faultless answered 14/3, 2018 at 23:47 Comment(0)
Q
11

i have encountered this problem and found a solution check the following link for a detailed description of the solution

https://laracasts.com/discuss/channels/laravel/paginate-while-returning-array-of-api-resource-objects-to-the-resource-collection?reply=575401

in short check the following code snippet that solve the problem

$data = SampleModel::paginate(10);
return ['key' => SampleModelResource::collection($data)->response()->getData(true)];
Quentinquercetin answered 24/1, 2020 at 11:2 Comment(0)
B
5

I notice result of resource collection must return individually to work correctly

return ItemMiniResource::collection(
        $items->paginate(10)
    );

It's works perfectly, but

$data['items'] = ItemMiniResource::collection(
        $items->paginate(10)
    );
return $data

not include paginate links

Beeline answered 26/3, 2018 at 21:53 Comment(0)
F
1

I have checked it locally and yes you are right it don't return the meta and links. So I have a solution which is working. Create a Post resource. And a resouce controller for your posts. Then on the single post api where you need comments, just return your comments explicitly.

class PostsResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'body' => $this->body,
            'comments' => Comment::paginate(5)
        ];
    }
}

So your controller code for the show which means the single post will be like this:

public function show($id)
{
  return new PostsResource(Post::find($id));
}
Forman answered 15/3, 2018 at 4:30 Comment(0)
C
0

There's several ways to get around the issue your having. That all depends on what's most important and what the response data needs to look like. As to your question:

Why does API Resource (using collection method or ResourceCollection) doesn't include pagination information when returned in array?

I believe what is happening is that a different function is being called to get the data to JSON depending on how the class is used. When a resource is returned directly from the controller, its toArray method is called. For resources, this method takes the incoming request object as a parameter. The paginator (for one) relies on the request object because it inspects the query to find what page the client is browsing for. Once the data is in array form, it's serialized to JSON before being sent to the client.

When the resource is used in an array, a request object isn't guaranteed to be available. So instead of the toArray method, I believe the toJson method is used. This method doesn't return any meta data, it just gets the data and turns it into a JSON string.

I've tested this briefly and the differences were consistent with the issue you describe.

Carousel answered 20/11, 2023 at 16:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.