F
Filamentβ€’15mo ago
Crylar

Is it possible to just merge new or existing values on a JSON field?

I have settings field with various settings, and would like to not remove old entries that are not available in a given form. e.g.
{"layout":{"is_restaurant":true}}
{"layout":{"is_restaurant":true}}
and
Forms\Components\Toggle::make('settings.is_valid')
Forms\Components\Toggle::make('settings.is_valid')
I would like to keep what is under "layout" but just add is_valid if it does not exist or update if it does, so the end json would look like:
{"layout":{"is_restaurant":true}, "is_valid":true}
{"layout":{"is_restaurant":true}, "is_valid":true}
4 Replies
Dan Harrin
Dan Harrinβ€’15mo ago
so 'settings.layout.is_restaurant' nesting is unlimited
Crylar
Crylarβ€’15mo ago
yeh but if I hit save the layout.is_restaurant is gone There might be many various settings stored on the column. I was wondering if there is a possibility to just merge and not completely overwrite.
Dan Harrin
Dan Harrinβ€’15mo ago
ah right maybe use mutateDataBeforeSave()?
Crylar
Crylarβ€’15mo ago
Yeh, this works. πŸ™‚
protected function mutateFormDataBeforeSave(array $data): array
{
$data['settings'] = array_merge($this->record->settings ?? [], $data['settings']);

return $data;
}
protected function mutateFormDataBeforeSave(array $data): array
{
$data['settings'] = array_merge($this->record->settings ?? [], $data['settings']);

return $data;
}
oh it looks like this preserves old values too if you write like so
Forms\Components\Section::make('Layout Settings')
->statePath('settings')
->schema([
Forms\Components\Toggle::make('layout.show_language_bar'),
])->collapsible()
Forms\Components\Section::make('Layout Settings')
->statePath('settings')
->schema([
Forms\Components\Toggle::make('layout.show_language_bar'),
])->collapsible()
If statePath empty then it just saves what is in the schema. I am leaving this for future reference if someone will be looking for similar.