Jonjie's avatar
Level 12

How to sort collection resource using the index

I'm trying to use collection resource, and need to sort the data by commented_at index. I tried using rsort to sort the collection but still not working. Please see the code below.

Problem:

The data is not showing sorted using the commented_at descending, it is still showing in ascending order.

Resources/CommentCollection.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class CommentCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'comment_count' => $this->count(),
            'links' => [
                'self' => url('/posts')
            ]
        ];
    }
}

Resources/Comment.php

<?php

namespace App\Http\Resources;

use App\Http\Resources\User as UserResource;
use Illuminate\Http\Resources\Json\JsonResource;

class Comment extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return rsort([
            'data' => [
                'type' => 'comments',
                'comment_id' => $this->id,
                'attributes' => [
                    'commented_by' => new UserResource($this->user),
                    'body' => $this->body,
                    'commented_at' => $this->created_at->diffForHumans()
                ]
            ],
            'links' => [
                'self' => url('/posts/' . $this->post_id)
            ]
        ]);
    }
}

Error:

"Cannot pass parameter 1 by reference"

[SOLUTION]:

  • Just added ->sortByDesc('created_at')->values()->all().
  • Modified the CommentCollection.php to this code:
public function toArray($request)
{
    return [
        'data' => $this->collection->sortByDesc('created_at')->values()->all(),
        'comment_count' => $this->count(),
        'links' => [
            'self' => url('/posts')
        ]
    ];
}
0 likes
9 replies
Sinnbeck's avatar

I would assume that you want to sort from the collection resource? Here you have just 1 item

Sinnbeck's avatar

@Jonjie so I assume you want to do the sorting in the CommentCollection. Be aware you need to do it before the return

public function toArray($request)
    {
        usort($this->collection, function () {}) ;//do sorting 
        return [
            'data' => $this->collection,
            'comment_count' => $this->count(),
            'links' => [
                'self' => url('/posts')
            ]
        ];
    }
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Or sort it when you get it from the database (what I would do)

1 like
ademtepe's avatar

I solved my problem like this:

$activityResourceCollection = ActivityResource::collection($activities);
$activities = $activityResourceCollection->toArray($request);
$activities = collect($activities)->sortBy('distanceInMeters');

distanceInMeters is calculated and added in the resource.

Tray2's avatar

@ademtepepro not sure why you are writing something totally irrelevant in a thread that was solved two years ago. However sorting in PHP if the data comes from a database is a big no, no. It slows the system down and hogs memory, any and all calculations can and should be done by the database.

Please or to participate in this conversation.