Dom
Dom

Reputation: 3438

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.

Upvotes: 0

Views: 1224

Answers (4)

Asur
Asur

Reputation: 4027

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 Illuminate\Database\Eloquent\Model;

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.

Upvotes: 1

IndianCoding
IndianCoding

Reputation: 2683

https://laravel.com/docs/5.7/collections#method-each

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

$apps->each(function ($item) {
        $item->some_key = 'some_value';
    });

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

Upvotes: 0

Joe
Joe

Reputation: 834

You're currently using Query Builder to build your queries, If you want to "automagically" add the property you should use Model Classes, It's basically the same with Query Builder.

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

    public function getakeyhereAttribute()
    {
        $data = //data from somewhere
        return $data;
    }
}

SomeClass::paginate(10); //will always include `akeyhere`

you can also use API Resource to handle your api output better.

Upvotes: 1

Farooq Ahmed Khan
Farooq Ahmed Khan

Reputation: 4094

getCollection() will return the data section of your collection. You can use Laravel collection function transform to update your objects

$apps->getCollection()->transform(function($iterator){
  return array_merge($iterator, [
   // add your extra (key, value) here
  ]);
});

Note

This approach suits when you don't want to update your core Models everytime you need an extra value in collection items.

BUT

If it is necessary and you need those extra attribute everywhere with this model you should go with Custom Attribute solution.

Upvotes: 0

Related Questions