Search code examples
laravellaravel-resource

What can be used instead of whenLoaded in Resource when data are set with setAttribute?


In PostCrudRepository class I read mediaProps from other class and write as Attribute:

public function get(int $id): Post
{
    $post = Post::getById($id)->firstOrFail();

    $mediaStorage= App::make(MediaStorageInterface::class);

    $mediaProps = $mediaStorage->getMediaById(
        id: $id,
        mediaId: $post->media_link,
        detailedInfo: true
    );

    $post->setAttribute('mediaProps', $mediaProps);

    return $post;
}

In controller I use

public function show(int $id): JsonResponse|MessageBag
{
    $post = $this->postCrudRepository->get(id: $id);

    return response()->json(['post' => (new PostResource($post))], JsonResponse::HTTP_OK);
}

and in PostResource :

<?php

namespace App\Http\Resources;

use App\Models\Post as PostModel;
use Illuminate\Http\Resources\Json\JsonResource;

class PostResource extends JsonResource
{

    public function toArray($request)
    {
        return [
            'id'         => $this->id,
            'created_at' => $this->created_at,
            'mediaProps' => new MediaPropsResource($this->whenLoaded('mediaProps')),
        ];
    }

}

But whenLoaded does work here, I suppose it works only for loaded models, but what have I to use for data set with setAttribute?

mediaProps can be an array or does not exists at all.


Solution

  • mediaProps Is a relationships?? I think its an attribute right? If yes, then whenLoaded will not work.

    In this case you have to make changes in your resource like.

      public function toArray($request)
        {
            $data = [
                'id' => $this->id,
                'created_at' => $this->created_at,
            ];
    
            if ($this->mediaProps) {
                $data['mediaProps'] = new MediaPropsResource($this->mediaProps);
            }
            return $data;
        }
    

    Hopefully this will help in your case.