I have a writable store in Svelte with an object. I'd like to display the properties and be able to change the property values as a user.
I'm able to get the properties and values to display in input tags with an on:input event to update the value in the store, but I get an error saying the sampleStore.set isn't a function. I tried to add a custom update function to the store, but I'm getting the same error.
What's the best way to do this?
Sample code below
Store.js
import { writable } from 'svelte/store';
function createSampleStore() {
const sampleStore = writable({
property1a: 'value1a',
property1b: 'value1b',
etc...
}
return {
subscribe: sampleStore.subscribe,
updateValue: (propertyName, propertyValue) =>
sampleStore.update((o) => {
o[propertyName] = propertyValue;
return o;
}),
};
}
export const sampleStore = createSampleStore();
InfoDisplay.svelte
<script>
import {sampleStore} from './sampleStore.js';
const propertyNames = Object.keys($sampleStore);
$: console.log($sampleStore);
</script>
<ul>
{#each propertyNames as propertyName}
<li>
{propertyName}:
<input
on:input={(value) =>
sampleStore.updateValue(propertyName, propertyValue)}
bind:value={$sampleStore[propertyName]}
/>
</li>
{/each}
</ul>
I tried to adjust the values shown in the input tag and have the values in the store be updated, but I kept getting the .set is not a function.
CodePudding user response:
The binding on the input value
creates a get/set relationship, you should only pass the value in and use the event to get it out:
<input
on:input={e => sampleStore.updateValue(propertyName, e.target.value)}
value={$sampleStore[propertyName]} /> <!-- no bind here -->
You also do not need a custom store to do this and could just use a writable
directly:
<input bind:value={$store[propertyName]} />