How to use Spatie Media Library in a json repeater field.

I have a requirement, where I need to use Spatie Media file upload and store the model_id in json column. Here is the required structure:
{
"items": [
{"key": "Key 1", "value": "value 1", "model_id": 1},
{"key": "Key 2", "value": "value 2", "model_id": 2},
]
}
{
"items": [
{"key": "Key 1", "value": "value 1", "model_id": 1},
{"key": "Key 2", "value": "value 2", "model_id": 2},
]
}
Here is what i am trying, It can read files from Media model. I am trying to find a way to set component when save form. When i dd() the form data, the items array contains only key/value properties but not the model_id
protected function mutateFormDataBeforeSave(array $data): array
{
dd($data);

return $data;
}
protected function mutateFormDataBeforeSave(array $data): array
{
dd($data);

return $data;
}
3 Replies
Mansoor Khan
Mansoor KhanOP14mo ago
Here is how i am implementing the repeater
Repeater::make('game.items')
->schema([
SpatieMediaLibraryFileUpload::make('media_id')
->disk('local')
->collection('game-image')
->visibility('private')
->conversion('thumb')
->loadStateFromRelationshipsUsing(function (SpatieMediaLibraryFileUpload $component, HasMedia $record) {
/** @var Model&HasMedia $record */
$files = $record->load('media')->getMedia('game-image')
->where('id', $component->getState())
->take(1)
->mapWithKeys(function (Media $file): array {
$uuid = $file->getAttributeValue('uuid');

return [$uuid => $uuid];
})
->toArray();

$component->state($files);
}),

Textarea::make('key')->rows(3),

Textarea::make('value')->rows(3),
]),
Repeater::make('game.items')
->schema([
SpatieMediaLibraryFileUpload::make('media_id')
->disk('local')
->collection('game-image')
->visibility('private')
->conversion('thumb')
->loadStateFromRelationshipsUsing(function (SpatieMediaLibraryFileUpload $component, HasMedia $record) {
/** @var Model&HasMedia $record */
$files = $record->load('media')->getMedia('game-image')
->where('id', $component->getState())
->take(1)
->mapWithKeys(function (Media $file): array {
$uuid = $file->getAttributeValue('uuid');

return [$uuid => $uuid];
})
->toArray();

$component->state($files);
}),

Textarea::make('key')->rows(3),

Textarea::make('value')->rows(3),
]),
I tried to tweak the saveUploadedFileUsing method to set state and return the model id but it did not work and the json array still has only key/value properties.
$this->saveUploadedFileUsing(static function (SpatieMediaLibraryFileUpload $component, TemporaryUploadedFile $file, ?Model $record) {
$component->state($media->id);

return $media->id;
});
$this->saveUploadedFileUsing(static function (SpatieMediaLibraryFileUpload $component, TemporaryUploadedFile $file, ?Model $record) {
$component->state($media->id);

return $media->id;
});
I know this might not be the best way to do it. I am open to suggestion and or any better implementation/solution.
skram
skram14mo ago
Hello Mansoor, Did you get this to work ?
Mansoor Khan
Mansoor KhanOP13mo ago
@skram I was able to make it work but with some hacks that i would not recommend.
Want results from more Discord servers?
Add your server