3

I am using laravel 5.5 API resource collection for showing list of products. I am using an array instead of the modal object. I got my list of items but i am not sure how to show item variant array in the response. The actual response array passing to the api resource are:

{
"ID": 3160,
"UserID": 3302,
"ItemName": "2",
"Description": "2",
"Price": 2,
"StockLimited": true,
"StockQuantity": 19,
"CurrencyCode": "USD",
"ImageUrl": "/images/items/Item3302-636434761494584365-qq5HFm.png",
"VariantItems": [
  {
    "ID": 3181,
    "ItemName": "2",
    "Price": 0,
    "StockLimited": false,
    "StockQuantity": 0,
    "CurrencyCode": "USD",
    "Variants": [
      {
        "Id": 1099,
        "Name": "Red",
        "VariantGroupId": 1027,
        "VariantGroupName": "Colour"
      },
      {
        "Id": 1111,
        "Name": "S",
        "VariantGroupId": 1028,
        "VariantGroupName": "Size"
      }
    ]
  },
  {
    "ID": 3182,
    "ItemName": "2",
    "Price": 0,
    "StockLimited": false,
    "StockQuantity": 0,
    "CurrencyCode": "USD",
    "Variants": [
      {
        "Id": 1099,
        "Name": "Red",
        "VariantGroupId": 1027,
        "VariantGroupName": "Colour"
      },
      {
        "Id": 1112,
        "Name": "M",
        "VariantGroupId": 1028,
        "VariantGroupName": "Size"
      }
    ]
  }

],
"MerchantName": "seller",
"VariantGroupLists": [
  {
    "VariantGroupName": "Colour",
    "Names": [
      "Red",
      "Grey",
      "Navy"
    ]
  },
  {
    "VariantGroupName": "Size",
    "Names": [
      "S",
      "M",
      "L",
      "XL"
    ]
  }
]  
}

My ItemResourceCollection

public function toArray($request)
{


    return [
        'data' => $this->collection->map(function ($item) use ($request) {
            return (new ItemResource($item))->toArray($request);
        })
    ];
}

My ItemResource

 public function toArray($request)
{

    return [
        "item_id" => $this->resource->ID,
        "item_name" => $this->resource->ItemName,
        "description" =>$this->resource->Description,
        "item_price"=>$this->resource->Price,
        "stock_qty"=>$this->resource->StockQuantity,
        "currency_code"=>$this->resource->CurrencyCode,
        "item_image_url"=>$this->resource->ImageUrl,

    ];

}

public function with($request)
{

    return ['item_varients' => [new ItemResource($this->resource->VariantItems)]]; 
}

What I am trying to achieve is this result:

[

{
    "item_id": 3160,
    "item_name": "BLACK COWL NECK DRESS WITH DIAMANTE DETAIL",
    "description": "Test test",
    "item_price": 16.99,
    "stock_qty": 20,
    "currency_code": "SGD",
    "item_image_url": "/images/items/Item18-636231488325192562-GoiIBl.png",
    "item_varients": [
      {
        "id": 29,
        "name": "Red",
        "varientgroupId": 11,
        "varientgroupname": "Color"
      }
    ]
  }
]

the with() method in ItemResource is not working. How do I add the "item_varients" array in the resource response?

3
  • 1
    Why not adding the item_varients property in the toArray() method directly? Commented Feb 19, 2018 at 6:55
  • @algorhythm: Can you please show me how should i do that? Commented Feb 19, 2018 at 7:04
  • And another point is, why are you filling you ItemResourceCollection this way? Why not using ItemResource::collection($this->collection) instead. Please read the documentation again at: laravel.com/docs/5.5/eloquent-resources#concept-overview Commented Feb 19, 2018 at 7:34

2 Answers 2

8

I would first move the line to add the item_varients property inside the method toArray like following:

public function toArray($request)
{
    return [
        "item_id" => $this->resource->ID,
        "item_name" => $this->resource->ItemName,
        "description" => $this->resource->Description,
        "item_price" => $this->resource->Price,
        "stock_qty" => $this->resource->StockQuantity,
        "currency_code" => $this->resource->CurrencyCode,
        "item_image_url" => $this->resource->ImageUrl,
        "item_varients" => [
            new ItemResource($this->resource->VariantItems)
        ]
    ]
}

Meta information

We do that because the with is meant for to add a meta information block or something similar. See https://laravel.com/docs/5.5/eloquent-resources#adding-meta-data The advantage when using the with method is, that multiple resources results in only one meta block. This is not what you want, I think.

Resource for VariantItem

I think you have to build a Resource class also for VariantItem. And because the VariantItems are a collection you also have to fill your array called item_variants similar to your ItemResourceCollection. So change your code to look like this:

public function toArray($request)
{
    /**
     * Prepare your variant items to have a collection
     *
     * @var Collection $variantItems
     */
    $variantItems = collect($this->resource->VariantItems);

    return [
        "item_id" => $this->resource->ID,
        "item_name" => $this->resource->ItemName,
        "description" => $this->resource->Description,
        "item_price" => $this->resource->Price,
        "stock_qty" > $this->resource->StockQuantity,
        "currency_code" => $this->resource->CurrencyCode,
        "item_image_url" => $this->resource->ImageUrl,
        "item_varients" => VariantItem::collection($variantItems)
    ]
}
Sign up to request clarification or add additional context in comments.

5 Comments

hi i tried both of your solution. however, i am getting this error in postman Exception: Failed calling App\Http\Resources\ItemResource::jsonSerialize() in file C:\wamp64\www\myproject\vendor\laravel\framework\src\Illuminate\Http\JsonResponse.php on line 71
I was changing my answer again. Have you tried that solution?
Maybe you can replace the ->map call with "item_varients" => VariantItem::collection($variantItems). But I'm not sure. Try it and tell me if it worked...
Yeah, that also works. thank you for teaching me these things. I am new to the API resource part.
So I changed my answer to explain the shorter solution. You can also improve the ItemResourceCollection this way ;)
0

Here is the best way to get specific fields using a collection

return [
        'id' => $this->id,
        'variant_item' => new CustomResource($this->user, ['item_id', 'item_name', 'item_size'])
    ];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.