Resources are only for returning JSON data (i.e as an API). So passing this to a blade view will never resolve the resource.
Looks like resource toArray method is not called with collection ?
In laravel 8 app I added resource with command
php artisan make:resource HtmlBlockResource
But calling it in controll :
$htmlBlocks = HtmlBlock::getById(1)->paginate(20);
return view('html-blocks.list', [
'htmlBlocks' => HtmlBlockResource::collection($htmlBlocks)
]);
I see only fields I got from db, looks like resource toArray method was ignored. I have in app/Http/Resources/HtmlBlockResource.php :
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class HtmlBlockResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
\Log::info( ' INSIDE HtmlBlockResource::' ); // I DO NOT SEE THIS LOG MESSAGE
return [
'name' => $this->name.'000000000',
'active' => $this->active,
'active_label' => $this->active.'AAAAAAA',
];
}
}
Reading https://laravel.com/docs/8.x/eloquent-resources I suppose that I use collection in valid way and do not see what is wrong ?
In my app :
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"jd-dotlogics/laravel-grapesjs": "^3",
"laravel/framework": "^8.75",
"laravel/sanctum": "^2.11",
"laravel/tinker": "^2.5",
"laravel/ui": "^3.4",
Thanks!
A resource's ->toArray() method expects the Request instance as a parameter. Try this:
return view('html-blocks.list', [
'htmlBlocks' => HtmlBlockResource::collection($htmlBlocks)->toArray(request())
]);
Or if you already have the request in your controller's method
return view('html-blocks.list', [
'htmlBlocks' => HtmlBlockResource::collection($htmlBlocks)->toArray($request)
]);
But as others said, this is not what resources were meant to. You will lose, for example, the ability to easily render the pagination links, as the view won't receive a Paginator instance anymore, but an array.
You will also need to iterate over records like this:
@foreach($htmlBlocks['data'] as $record)
{{ $record['field'] }}<br>
@endforeach
All paginated collections wrap the list of records into a data key, and your records won't be objects anymore, so you will need to access their fields with array notation, note also that object values, such as dates like created_at and updated_at, won't be objects anymore, so you cannot call ->format(...) on them.
I see you want to transform data, by concatenating a suffix on that. My suggestion is that you either:
- Use accessors https://laravel.com/docs/9.x/eloquent-mutators#defining-an-accessor
- Transform the Paginator data using
->through()like the following
$htmlBlocks = HtmlBlock::query()
->getById(1)
->paginate(20)
->through(function (HtmlBlock $record) {
$record->name = $record->name . '000000000';
$record->active_label = $record->active_label . 'AAAAAAA';
return $record;
});
return view('html-blocks.list', ['htmlBlocks' => $htmlBlocks]);
Please or to participate in this conversation.