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?
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)
]
]
}
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.
VariantItem
I think you have to build a Resource
class also for VariantItem
. And because the VariantItem
s 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)
]
}