Home > Enterprise >  How to update Svelte writable store values with input tag
How to update Svelte writable store values with input tag

Time:02-02

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]} />

REPL

  • Related