key-value and json arrays: {closure}(): Argument #1 ($value) must be of type ?string, array given
Hey all,
I'm working on an admin section for my portfolio page.
The data is from a bunch of Markdown files with some frontmatter; this frontmatter has been converted and stored as json in a sqlite database. When editing the Project, I chose to display the frontmatter with a KeyValue form component. After trying to save an instance without changing the values (meaning they should be valid), I get the following error:
Could it be that an array value is incompatible with the KeyValue component? Or am I doing something wrong ?
Solution:Jump to solution
Looking at it, you are storing as an array but we load that magically and it renders ok. But it should always be stored as a string in a keyValue.... you could look to cast it to a string with attributes.
If you are insistent on storing it as an Array you can use this model class for your project using the get/set attributes
```php...
26 Replies
Yes 'KeyValue' needs to be a string as it's the value
ah, and is there no way to convert it to and from an array on save ? I've been trying to use mutateFormDataBeforeSave, but it doesn't look to be triggering ?
Is it the key value pair field or the keyValue?
the value can be an array (I know which ones are arrayis in advance)
So the field should be cast as an Array on the model
done
If that's done it should be ok then...
an example of data is this:
Shows up fine, with the stack element separated by , but then the error happens when I try to save
so could it be that it gets interpreted as an array when it gets sent back to be saved ? maybe because of the cast ?
It will be failing at "stack":["typescript","another tech"] surely? because stack is an array
yes, but only on save I think (it displays fine). Is there a way to handle saving this field manually ? I thought maybe mutateFormDataBeforeSaving would work, but it does not even trigger, it seems
Can you provide the field code
upping this since I'm still trying to make this work; I tried using mutateFormDataBeforeSave and handleRecordUpdate, but neither gets called before the error is thrown 😦
Can you provide an example repo and we can test it
https://github.com/matfire/filament-kv-repro
here it is
GitHub
GitHub - matfire/filament-kv-repro
Contribute to matfire/filament-kv-repro development by creating an account on GitHub.
Thanks, why are you saving it as an array to the DB?
Solution
Looking at it, you are storing as an array but we load that magically and it renders ok. But it should always be stored as a string in a keyValue.... you could look to cast it to a string with attributes.
If you are insistent on storing it as an Array you can use this model class for your project using the get/set attributes
It will work for tags only
hey, thank you so much! Works like a charm on the filament admin!
but now it doesn't load properly on the rest of the website because it gets converted to a string (so looping over it does not work anymore :(). But I could change that section to explode the string it receives, though it seems a bit weird and inefficient (imploding to explode it right after...) ?
They are stored as an array because of the way Eloquent does casts automatically, so i don't know how hard it would be to customize that process...
Right I think I get you, why not just store it as strings and then explode on the frontend?
It is a string by default, the only difference seems that you have some values stored as an array some how for tags
I was also thinking of that, but I don't know how hard it would be to change how Laravel handles converting to an array. This is the import script I'm using on the actual website.
getFrontMatter
returns an array representing the frontmatter on a markdown file. It is stored in the database as a JSON columnDude remove my getter/setter and just change:
to
and re-run the import and everything will be fine.
just tried it, getting:
on the changed line 😦
ahh sorry!!! can you show the getFrontMatter() function
I didn't make it, it comes from the commonmark packages:
League\CommonMark\Extension\FrontMatter\Data\SymfonyYamlFrontMatterParser
League\CommonMark\Extension\FrontMatter\FrontMatterParser
I'll see if I can find some readable source code
Ok so it's ok you can do this instead
something like that should work
the import worked! thanks!
just generalized the code a bit to convert all arrays into a comma-separated string to ease the transition of all other models.