How to add an element to JSON Laravel pagination object

With this request:

$apps = DB::select("select 
        a.id, a.app_name, a.country_id, a.feature_id, a.organization_id, a.status_id,
        o.organization_name, f.feature_name
        from apps as a
        left join organizations as o on o.id = a.organization_id
        left join features as f on f.id = a.feature_id
        order by app_name
        ");
    
    $apps = DB::table('apps')->orderBy('app_name')->paginate(10);
    return response()->json($apps);

I get this json:

{
"current_page": 1,
"data": [
    {
        "id": "ab221e40-e711-11e8-b124-95a6d9405f4b",
        "app_name": "Asf autre",
        "country_id": "FR",
        "feature_id": "5724ecad-f8d3-3b5f-bd36-d62e97a26798",
        "organization_id": "44720e79-eaf9-300a-bbcd-cdfce46dbf54",
        "status_id": "PROD",
        "created_by": "6d2aeca8-a29d-38b0-bbd7-8f0c9656ca3b",
        "updated_by": null,
        "created_at": "2018-11-13 07:59:30",
        "updated_at": "2018-11-13 07:59:30"
    },
    {
        "id": "f4ccb480-e711-11e8-a6e6-3b8112548306",
        "app_name": "Asf pays",
       .....

Perfect.

I would like to add some keys in each element of the “data” key. To have this kind of json:

{
"current_page": 1,
"data": [
    {
        "akeyhere" : "avaluehere",
        "id": "ab221e40-e711-11e8-b124-95a6d9405f4b",
        "app_name": "Asf autre",
        "country_id": "FR",
        "feature_id": "5724ecad-f8d3-3b5f-bd36-d62e97a26798",
        "organization_id": "44720e79-eaf9-300a-bbcd-cdfce46dbf54",
        "status_id": "PROD",
        "created_by": "6d2aeca8-a29d-38b0-bbd7-8f0c9656ca3b",
        "updated_by": null,
        "created_at": "2018-11-13 07:59:30",
        "updated_at": "2018-11-13 07:59:30"
    },
    {
        "akeyhere" : "anothervalue",
        "id": "f4ccb480-e711-11e8-a6e6-3b8112548306",
       .....

How would you do that? I think I must use “ressources” notion but I never used that and I tried without success.

Answer

If you are casting objects to json, you can use the $append variable in the model and an accessor like this:

// Get your data using eloquent to retrieve models

$apps = App::orderBy('app_name')->paginate(10);

return response()->json($apps);

And on your model you add:

<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class App extends Model
{
    protected $appends = ['akeyhere'];

    public function getAkeyhereAttribute()
    {
        return 'avaluehere';
    }
}

If you want to stick with raw queries or the query builder you have a couple of options aswell:

~ Iterate the result and append the desired elements.

$paginator->getCollection()->map(function ($element) {

    $element['akeyhere'] = 'avaluehere';

    return $element;
})

~ Hydrate the result set and then cast it to json

$apps = DB::table('apps')->orderBy('app_name')->paginate(10);

$apps = App::hydrate($apps);

return response()->json($apps);

This will turn a result set of arrays into models, so you could now take advantage of the append feature.

IMO you are best taking advantage of the model features Laravel provides, so if I were you I would go with the first option.

Hope this helps you.

Leave a Reply

Your email address will not be published. Required fields are marked *