'How can I get a svelte app to update fields correctly?
I have a svelte application (see repl here)
I want to be able to select a car from the select box. The colour field should update with the default colour for the car. This can then be overridden by the user in the colour input, and the display updated
This works for the first car selected, but after that the colour is always for the previous car.
What am I doing wrong?
App.svelte
<script>
import DisplayMessage from './display.svelte'
import Car from './cars.svelte'
let car = 'default car'
let colour = 'default colour'
$: message = displayCar(car, colour)
function displayCar(car, colour) {
if (!car || !colour) {
return 'No car selected'
}
return `The ${car} is ${colour}`
}
</script>
<DisplayMessage bind:display_message={message}/>
<Car bind:car_name={car} bind:colour={colour}/>
cars.svelte
<script>
let makes = {Audi: 'black', BMW: 'blue', Jaguar: 'green'}
let cars = []
for (const [key, value] of Object.entries(makes)) {
cars.push(key);
}
export let car_name = '';
export let colour = '';
$: colour = makes[car_name]
</script>
<div class="double-column">
<div>car</div>
<select id="car-select" bind:value={car_name}>
{#each cars as car}
<option value={car}>
{car}
</option>
{/each}
</select>
</div>
<input type="text" bind:value={colour} placeholder="colour"/>
display.svlete
<div id="display-message">{display_message}</div>
<script>
export let display_message = ''
</script>
Solution 1:[1]
You are using bind:display_message={message}
This creates a two way relation between display_message and message which is somehow messed up. There are plenty of updates happening at once, a new car means a new string, a new colour means a new string, and your binding means another string is being send back.
It's best to be extra carefull when using bind: and especially not bind to reactive variables because the data flow is fragile (on top it doesn't really make sense because the reactive variable is dependent on variables in your parent component)
Since you (very likely) do not need the two way binding just remove bind:this here and it will work fine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Psionman |
