We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
I've run into a problem where I've used an attribute casted as an array in a Laravel resource and I wanted to preserve the keys of that array. By default, Laravel will re-index the array, which is not what I wanted.
To preserve the keys, you can use the preserveKeys
method on the collection. Here's an example:
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class User extends JsonResource
{
/**
* Indicates if the resource's collection keys should be preserved.
*
* @var bool
*/
public $preserveKeys = true;
}
When the preserveKeys
property is set to true
, collection keys will be preserved:
use App\User;
use App\Http\Resources\User as UserResource;
Route::get('/user', function () {
return UserResource::collection(User::all()->keyBy->id);
});
What I didn't know is that this didn't only apply to the resource, but also to the attributes of the resource.
If you don't want to enable this option for the complete resource, once approach you can take is to create a new resource like this:
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ArrayPreservingKeysResource extends JsonResource
{
/**
* Indicates if the resource's collection keys should be preserved.
*
* @var bool
*/
public $preserveKeys = true;
public function toArray(Request $request): array
{
return $this->resource;
}
}
You can then apply to any array you want to preserve the keys of in the resource:
namespace App\Http\Resources;
use App\Domains\Predictions\Models\Prediction;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/**
* @mixin Company
*/
class CompanyResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'data' => new ArrayPreservingKeysResource($this->data),
];
}
}
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.