mstdmstd's avatar

I do not have meta data in laravel's resources

Hello, In my laravel 5 apps I returned json in request controls, like:

        $retArray['tasks']          = $taskList;
        $retArray['tasks_total_count'] = $tasks_total_count;
        return response()->json($retArray, 200);

including additive parameters like tasks_total_count, which was used for pagination.

In laravel 6 app I use resources, like:

<?php

namespace App\Http\Resources\Admin;

use App\Facades\MyFuncsClass;
use Illuminate\Http\Resources\Json\JsonResource;

class Task extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'slug' => $this->slug,
            'price' => $this->price,
            ...
            'taskRequireSkills' => !empty($this->taskRequireSkills) ? $this->taskRequireSkills : [],
            'events' => !empty($this->events) ? $this->events : [],
            'events_count' => !empty($this->events_count) ? $this->events_count : 0,
            'created_at' => $this->created_at,
            ...
        ];
    }

    public function with($request)
    {
        return [
            'meta' => [
                'version'=>'1.0.2'
            ]
        ];
    }

}

I want to add some additive meta data, like version but in my browser I do not see this meta data, : https://prnt.sc/qm4t8y Also which is correct way to add tasks_total_count parameter to my Resource, which is diffrent for any request?

Thanks!

0 likes
8 replies
Sti3bas's avatar

@mstdmstd with method is only available for ResourceCollection. Take a look at Top Level Meta Data section in https://laravel.com/docs/6.x/eloquent-resources#adding-meta-data

  1. Create TaskCollection:
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class TaskCollection extends ResourceCollection
{
    public function with($request)
    {
        return [
            'meta' => [
                'version' => '1.0.2',
            ],
        ];
    }
}
  1. Return it in the controller:
return new TaskCollection(Task::all());
1 like
mstdmstd's avatar

Thanks for your feedback! I made like :

<?php

namespace App\Http\Resources;
use App\Facades\MyFuncsClass;

use Illuminate\Http\Resources\Json\ResourceCollection;

class TaskCollection extends ResourceCollection
{
    public function toArray($task)
    {

        return [
            $this->collection->transform(function($task){
                return [
                    'id' => $task->id,
                    'name' => $task->name,
                    'slug' => $task->slug,
                    'price' => $task->price,
                    'description' => $task->description,
                    'creator_id' => $task->creator_id,
                    'leader_id' => $task->leader_id,
                    'category_id' => $task->category_id,
                    'priority' => $task->priority,
                    'status' => $task->status,

                    'date_start' => $task->date_start,
                    'date_start_formatted' => MyFuncsClass::mySqlToStringDate($task->date_start),

                    'date_end' => $task->date_end,
                    'date_end_formatted' => MyFuncsClass::mySqlToStringDate($task->date_end),

                    'needs_reports' => $task->needs_reports,
                    'image' => $task->image,
                    'leader_name' => $task->leader_name,
                    'category_name' => $task->category_name,
                    'category_slug' => $task->category_slug,
                    'filenameData' => $task->filenameData,
                    'taskRequireSkills' => !empty($task->taskRequireSkills) ? $task->taskRequireSkills : [],
                    'events' => !empty($task->events) ? $task->events : [],
                    'events_count' => !empty($task->events_count) ? $task->events_count : 0,
                    'created_at' => $task->created_at,
                    'updated_at' => $task->updated_at,
                ];
            }),
        ];

    }

    public function with($task)
    {
        return [
            'meta' => [
                'version'=>'1.0.2'
            ]
        ];
    }

}

and the only question I have is how to pass 1 more parameter tasks_total_count, which I need for pagination of my page? I can not put it in “with” method as it is changable value for any request. I can set this value in any $task row, but this way seems not good...

mstdmstd's avatar

Thanks! One More question on client(vuejs.axios request) to read data I have to write:

                        this.tasks = response.data.data[0]
                        this.tasks_total_count = response.data.meta.tasks_total_count

If there is a way to get rid away of .data[0] ?

mstdmstd's avatar

Yes, in my app/Providers/AppServiceProvider.php I have lines :

<?php

namespace App\Providers;

use Auth;
use Validator;
use Illuminate\Http\Resources\Json\Resource;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {

        Resource::withoutWrapping();

But if line above commented or not I have to use :

                        this.tasks = response.data.data[0]

in both cases?

Is withoutWrapping parameter applicable ResourceCollection data? Are there some otgher parameters involved ?

Sti3bas's avatar

@mstdmstd do you tried to remove nested array?:

return $this->collection->transform(function($task) {
   //...
})->map->toArray($request)->all();

Instead of:

return [
   $this->collection->transform(function($task){
      //...
   })
];
mstdmstd's avatar

Yes, I saw that I have nested arrays, but with your last code example I ghot errors and do now how to handle it. I found decitions here https://stackoverflow.com/questions/46388205/laravel-5-5-api-resources-for-collections-standalone-data

In code code it was listing and when I need to get 1 row I have to writeL

            loadTaskDetails() {
                axios({url: this.apiUrl + '/get_task_by_slug/' + this.task_slug, data: {}, method: 'get'})
                    .then(response => {
                        this.taskRow = response.data.data[0][0]
                        this.task_assigned_to_users_count = response.data.meta.task_assigned_to_users_count

syntax looks terrible, but that works for me...

Please or to participate in this conversation.