S
SolidJS11mo ago
Ziltoid

How do I modify a member of an object in an array in a SolidJS Store using the SetStoreFunction?

(Re-post from https://stackoverflow.com/questions/76843586/how-do-i-modify-a-member-of-an-object-in-an-array-in-a-solidjs-store-using-the-s , if answered here or vice versa I'll update the other ) Full code is in the stack overflow link^ I'm trying to modify an element of a SolidJS store using the SetStoreFunction (setExpressions). The SetStoreFunction accepts 'Path Syntax' as described in the docs: https://www.solidjs.com/docs/latest/api#updating-stores , so I am trying to do something similar here, but it doesn't work:
const [expressions, setExpressions] = createStore<Expression[]>([])

(...)

setExpressions( //todo the problem seems to be here somewhere:
expression => expression.id == id, // first we filter the array to those Expression objects which match the id specified
'value', // Then we select the value member of Expression
value // Then we pass the new value to be set
)
const [expressions, setExpressions] = createStore<Expression[]>([])

(...)

setExpressions( //todo the problem seems to be here somewhere:
expression => expression.id == id, // first we filter the array to those Expression objects which match the id specified
'value', // Then we select the value member of Expression
value // Then we pass the new value to be set
)
I've tried double checking the path syntax for SetStoreFunction (setExpressions) against the docs, and I still believe it should work. In the full code, I'm expecting that when I call getExpressionSetValue(id), it returns a setValue string => void function on the expression with that id. And that I can call setValue("abc") to set the value on that expression to abc. This should allow me to type into the text field to update the value. But instead no change happens when I type into the text field. I'm also not sure how to dive deeper into debugging this issue (kinda new to web dev) so I'm open to suggestions there as well (leave a comment? many thanks). Any thoughts?
Stack Overflow
How do I modify a member of an object in an array in a SolidJS Stor...
Full code is at the bottom. I'm trying to modify an element of a SolidJS store using the SetStoreFunction (setExpressions). The SetStoreFunction accepts 'Path Syntax' as described in the docs: http...
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
6 Replies
Nathan
Nathan11mo ago
Not directly what you're asking, but I noticed the bit about typing into the textfield not working. The onChange prop should be onInput. The native behavior of onChange is to only trigger when the element loses focus. I think React does some weird stuff to make that different. Oh, actually, that might be the source of your problem
mdynnl
mdynnl11mo ago
the callback of For works like a component in itself and by spreading the item in that callback access the properties eagerly and the value passed to another place are fixed to that time.
const [get, set] = createSignal(0)

// calling the signal inside the effect is
// what makes the effect re-run when the signal changes
createEffect(() => {
// what we call tracking scope
console.log(get()) // signal and effect bind each other so that both side are aware
})
// vs
const valueNow = get() // 0
// now the effect just sees a static value
createEffect(() => console.log(valueNow))

// similarly with stores
const store = {
get value() {
return get()
}
}

createEffect(() => console.log(store.value))
// vs
const { value } = store
createEffect(() => console.log(value))
const [get, set] = createSignal(0)

// calling the signal inside the effect is
// what makes the effect re-run when the signal changes
createEffect(() => {
// what we call tracking scope
console.log(get()) // signal and effect bind each other so that both side are aware
})
// vs
const valueNow = get() // 0
// now the effect just sees a static value
createEffect(() => console.log(valueNow))

// similarly with stores
const store = {
get value() {
return get()
}
}

createEffect(() => console.log(store.value))
// vs
const { value } = store
createEffect(() => console.log(value))
Ziltoid
Ziltoid11mo ago
I don't think so- I'm using Kobalte which uses onChange: https://kobalte.dev/docs/core/components/text-field#controlled-value , their example works on any input, not just focus change I don't fully understand what you're saying yet but I think that is the problem. I tried the following:
const getExpressionSetValue = (id: number) => {
return (value: string) => {
console.log(value)
setExpressions(expression => expression.id == id, 'value', value)
console.log(expressions)
}
}
const getExpressionSetValue = (id: number) => {
return (value: string) => {
console.log(value)
setExpressions(expression => expression.id == id, 'value', value)
console.log(expressions)
}
}
And I am able to observe the store being updated correctly, the issue is that the text fields aren't being updated, as you mentioned. Now I need to figure out how to make it so that the fields update when the store updates. My expectation was that it would automatically be handled when using a store. I'm not sure if I'm using it wrong or what the problem is Update: I tried switching to native UI elements instead of Kobalte and now it works. See the SO post for what I did. However it doesn't explain the behavior or make sense to me, and I'd like to use Kobalte, so this is still an unresolved issue. I'll try asking in the Kobalte channel
Nathan
Nathan11mo ago
Hmm, try forwarding onInput to TextField.Input. That's what the Modular Forms docs suggest doing. Something like this:
const MyComponent = (props) => {
<TextField.Root value={props.value}>
...
<TextField.Input onInput={props.onInput} />
...
</TextField.Root>
}
const MyComponent = (props) => {
<TextField.Root value={props.value}>
...
<TextField.Input onInput={props.onInput} />
...
</TextField.Root>
}
https://modularforms.dev/solid/guides/kobalte
Ziltoid
Ziltoid11mo ago
Got an answer from @foolswisdom on the SO post, the issue was hinted at by @mdynnl but I didn't understand tracking/reactive scope well enough to understand. This makes it much more clear, and also why the native input works even though the tracking scope issue was still there. Many thanks to all!
Stack Overflow
How do I modify a member of an object in an array in a SolidJS Stor...
I'm trying to modify an element of a SolidJS store using the SetStoreFunction (setExpressions), so that the View for the store's values are updated, e.g. when text is entered into a text field. I
foolswisdom
foolswisdom11mo ago
Great!