t0berius's avatar
Level 13

keep Resource order when adding datausing toArray()

Assume the following laravel code

class OrderCollection extends ResourceCollection {

public function toArray($request)
{
    return [
        'data' => $this->collection->map(function ($order) {
            return new OrderResource($order);
        }),
        'meta' => [
            'server' => "someserver",
        ]
    ];
}

//remove some links from pagination
public function paginationInformation($request, $paginated, $default)
{
    unset($default['meta']['links']);
    return $default;
}

As soon as I include the JSON object

        'meta' => [
            'server' => "someserver",
        ]

The complete order of the returned JSON is changed. With "server"

{
	"data": [
	    {
			//omitted
	    }
	],
	"meta": {
	    "server": "someserver",
	    "current_page": 1,
	    "from": 1,
	    "last_page": 1,
	    "per_page": 15,
	    "to": 3,
	    "total": 3
	},
	"links": {
	    "prev": null,
	    "next": null
	}
}

Without server

{
	"data": [
	    {
	    }
	],
	"links": {
	    "prev": null,
	    "next": null
	},
	"meta": {
	    "current_page": 1,
	    "from": 1,
	    "last_page": 1,
	    "per_page": 15,
	    "to": 3,
	    "total": 3
	}
}

I removed some data from the JSON structure, just to keep it simple.

I would like meta to always be at the end AND include the server.

0 likes
3 replies
LaryAI's avatar
Level 58

To ensure that the meta key is always at the end of your JSON response while including the server information, you can manipulate the order of the keys in the toArray method. One way to achieve this is by using the array_merge function to append the meta key at the end of the array.

Here's how you can modify your toArray method:

class OrderCollection extends ResourceCollection
{
    public function toArray($request)
    {
        $data = [
            'data' => $this->collection->map(function ($order) {
                return new OrderResource($order);
            }),
        ];

        $meta = [
            'meta' => array_merge(
                ['server' => 'someserver'],
                $this->paginationInformation($request, $this->resource->toArray(), [])
            )
        ];

        return array_merge($data, $meta);
    }

    // Remove some links from pagination
    public function paginationInformation($request, $paginated, $default)
    {
        unset($default['meta']['links']);
        return $default;
    }
}

In this solution:

  1. We first create the $data array containing the data key.
  2. We then create the $meta array, ensuring that the server key is included and merged with the existing pagination metadata.
  3. Finally, we merge the $data and $meta arrays, ensuring that meta is always at the end of the JSON response.

This approach ensures that the meta key, including the server information, is always appended at the end of the JSON response.

t0berius's avatar
Level 13

@laryai the solution from AI sadly doesn't work, the order is stil incorrect (data / meta / links), not as requested (data / links / meta).

t0berius's avatar
t0berius
OP
Best Answer
Level 13

Solved just by using:

public function paginationInformation($request, $paginated, $default)
{
    //remove links attribute
    unset($default['meta']['links']);

    //additional attribute
    $default['meta']['server'] = "someserver";

    return $default;
}

Please or to participate in this conversation.