0
votes

I have created an API Resource:

class OrderResource extends JsonResource
{

    public function toArray($request)
    {
        return [
            "id" => $this->Id,
            "photo" => ''
        ];
    }
}

In controller I get data from model OrderModel the put data into resource OrderResource:

public function show($id)
{
        $order = OrderModel::with('OrderPhoto')->findOrFail(1);

        return new OrderResource($order);
}

So, I tried to use relation OrderPhoto in OrderResource like this:

public function toArray($request)
    {
        return [
            "id" => $this->Id,
            "photo" => OrderPhotoResource::collection($this->whenLoaded('OrderPhoto')),
        ];
    }

But it does not work and gives this error:

Undefined property: Illuminate\Database\Query\Builder::$map

I did dd($this) in resource and what I got:

enter image description here

Class OrderPhoto:

class OrderPhoto extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}
1
Could you also place the code of the OrderPhotoResource class?Kenny Horna
Sure it is simple, postedOPV
So, in line "photo" => OrderPhotoResource::collection($this->whenLoaded('OrderPhoto')) I try to get loaded relation data OrderPhoto and put to OrderPhotoResourceOPV

1 Answers

2
votes

TL;DR

Try this in your OrderResource:

use OrderPhoto as OrderPhotoResource;

//

public function toArray($request)
{
    return [
        "id" => $this->Id,
        "photo" => new OrderPhotoResource($this->whenLoaded('OrderPhoto')),
    ];
}

Explanation

As you can see, you are already defining the OrderPhoto as a Resource Collection:

class OrderPhoto extends ResourceCollection // <-- note the extended class

So in this case, you'll need to use this class instanciating it and pass in it the collection, instead of using the static method collection.

When you define a API Resource for a single object, like this:

php artisan make:resource PostResource

you use it like below:

$post = Post::find(1);

return new PostResource($post);

And if you want to use an API Resource to format a collection of resources instead of a single one, you need to do this:

$posts = Post::all();

return PostResource::collection($posts); // <-- note the ::collection part

Controlling the metadata

If you want to have a total control of the returned metadata in the response, define a custom API Resource Collection class instead.

Generate the class as a collection (adding the 'Collection' at the end or using the flag --collection):

php artisan make:resource PostResourceCollection

then, after customize it:

$posts = Post::all();

return new PostResourceCollection($posts); // <-- instantiating the class