user2502794
user2502794

Reputation: 137

Using a Svelte each block, how do you bind:value to a to a variable stored outside the array, but reference inside the array?

Here is a simple example of my problem.

I have an array which will hold a list of questions. It is initialized holding only one question. Once the user answers the first question, I will push a followup question to the array using a reactive statement.

Here is my code in the Svelte REPL: https://svelte.dev/repl/f950ce9c8ea94f0f9d1bef8f87680be0?version=3.20.1

I just need the atHome variable on line 2 to be true or false based upon the user's response.

    let atHome = null;
    let questions = [
    {
      question: 'Are you stuck at home?',
      bindValue: atHome,
    },
  ];
</script>

{#each questions as question}
    <div class="VitWotc-question">
            <ul>
                <li>Script stuck at home => {atHome}</li>
                <li>Iteration Bind stuckatHome => {question.bindValue}</li>
            </ul>
      <p>{question.question}</p>
      <label>
        <input type="radio" bind:group={question.bindValue} value={true} />
        Yes
      </label>
      <label>
        <input type="radio" bind:group={question.bindValue} value={false} />
        No
      </label>
    </div>
  {/each}```

Upvotes: 2

Views: 1848

Answers (1)

V. Sambor
V. Sambor

Reputation: 13399

You can use on:change event listener for the inputs and then pass the parameters to the handler, where you can assign the same values for the question.value and for the external variable.

Something like this:

<script>
    let atHome = null;
    let questions = {
        atHome: {
            question: 'Are you stuck at home?',
            value: null
        }
    }
    let questionArray = []
    $: {
        questionArray = []
        for (let key in questions) {
            questionArray.push(questions[key])
        }
        console.log(questions.atHome.value);

    }

    function handleChange(event, question, atHome) {
        question.value = event.target.value === "true"
        atHome = question.value;
        console.log(question);
        console.log(atHome);
    }
</script>
{#each questionArray as question}
    <div class="VitWotc-question">
            <ul>
                <li>Script stuck at home => {atHome}</li>
                <li>Iteration Bind stuckatHome => {question.value}</li>
            </ul>
      <p>{question.question}  </p>
      <label>
        <input type="radio" name="q1" on:change={(e) => handleChange(e,question, atHome)} value={true} />
        Yes
      </label>
      <label>
        <input type="radio" name="q1" on:change={(e) => handleChange(e,question, atHome)} value={false} />
        No
      </label>
    </div>
  {/each}

Note: I have added the same name attribute to the input elements in order to keep them as a group. Maybe you'll have to pass that via the question object and bind it to the input, so that you don't have to write it manually as I did...

Here you have the REPL link: https://svelte.dev/repl/a2dc24f98ac1429db6964737522816e5?version=3.20.1

Don't forget to check the browser console to see that is working.

Upvotes: 0

Related Questions