0

I have a collection of Items. Now, before I am sending it though my api, I want to change a value of the model (but I don't want to update my model in the database).

Now I want to loop though my collection and return it as json, but I am getting invalid Payload.

Here is the code I perform:

$trainees = Trainee::select();
        if(!$request->user()->hasPermission('read-trainees')) {
            $trainees->where('status', 1)->where('visible', 1);
        } else {
            $trainees->with(array('user'=>function($query){
                $query->select('id','firstname', 'lastname');
            }));
            $trainees->select('user_id');
        }
        $trainees->select('interested_jobs', 'graduation');
        $trainees = $trainees->get();
        return $trainees
            ->map(function ($item) {
                $item->id = encrypt($item->id);
                return $item;
            })
            ->toJson();
Patrick Schocke
  • 1,493
  • 2
  • 13
  • 25

2 Answers2

4

You can achieve this in several ways.

Every Eloquent collection extends the Collection class, that let you use helpful methods like map() or each():

// get your collection
$trainees = Trainee::all();

// customize them
$trainees->each(function ($trainee) {
  $trainee->id = encrypt($item->id);
});

return $trainees;

PS: By default, when returning an array/collection to an API Laravel will return it as JSON.


The second approach, more granular and recommended in my opinion, is to use API Resources. From the documentation:

When building an API, you may need a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application's users. Laravel's resource classes allow you to expressively and easily transform your models and model collections into JSON.

So, you'll need to:

1. Generate your API Resource

php artisan make:resource TraineeResource

2. Customize it

App\Http\Resources\TraineeResource.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class TraineeResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => encrypt($this->id),
            // ...
        ];
    }
}

3. Apply it

In your controller:

App/Http/Controllers/MyCoolController.php

use App\Http\Resources\TraineeResource;

public function aCoolMethod(Request $request)
{
    // get your collection
    $trainees = Trainee::all();

    // return it
    return TraineeResource::collection($trainees);
}
Kenny Horna
  • 13,485
  • 4
  • 44
  • 71
1

You can use the map function to change the data for each item in a collection.

return $trainees
    ->map(function ($item) {
        $item->id = decrypt($item->id);
        return $item;
    })
    ->toJson();
Jerodev
  • 32,252
  • 11
  • 87
  • 108