Search code examples
javascripthtmlsvelte

refresh svelte select component after adding an option


I am trying to make a select component update itself after adding an option but I can't. Here is my code:

<script>
  const options = ['first_option']
  const addEventSignal = () => {
    const option = prompt('Please enter new option', '')
    if (option) {
      options.push(option)
    }
  }
  const doSomething = event => {
    console.log(event)
  }
</script>

<style></style>

<div>
  <select bind:value={options} on:change={doSomething}>
    {#if options}
      {#each options as option}
        <option value={option}>{option}</option>
      {/each}
    {/if}
  </select>
  <button type="button" on:click={addEventSignal}>Add Signal</button>
</div>

If I reload the component it shows the new option but I would like to have the new option in the select list as soon as the input dialog is gone.


Solution

  • Svelte doesn't detect the mutation of your options object:

    options.push(option)
    

    It only tracks assignments, with =. A very common solution to make the compiler aware of the modification is this kind of situation is self-assigment:

    // you'd also have to make it a `let`, of course
    options.push(option)
    
    // this, Svelte will see!
    options = options
    

    You can call that a Sveltism.

    Reactivity will ensue, and your select's options should be updated immediately. See details in this section of the tutorial.