How to get a select to show values in svelte

I have a select in my svelte app. I cannot get it to display it's initial value (default_car) or, after I have clicked on a car, the selected_car

REPL

App.svelte

<Car {cars} on:message={carChanged} /> <div> <button on:click={getDataStore}>Get data</button> </div> <script> import Car from './Cars.svelte' import { getBlankCars, getCarData } from './store.js' let cars = getBlankCars(); let car; function carChanged(event) { car = event.detail.value; console.log('selected car:', car); } function getDataStore() { cars = getCarData(); } </script> 

Cars.svelte

<select bind:value={selected_car} on:click={selectCar}> {#each car_list as car} <option value={car}> {car} </option> {/each} </select> <script> import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher(); let started = false; export let cars; $cars = $cars; let car_list; $: car_list = carList($cars); let default_car = 'BMW'; let selected_car; $: selected_car = getInitialCar($cars) $: selected_car = default_car function getInitialCar() { if (!started) { selected_car = default_car; if (selected_car) { started = true; selectCar(); } } selected_car = default_car } function carList(cars) { let car_list = []; for (const [key, value] of Object.entries(cars)) { car_list.push(key); } return car_list; } function selectCar() { dispatch('message', { value: selected_car }); } </script> 

store.js

import { writable } from 'svelte/store' let blank_cars = {} let raw_cars = {'Audi': 'red', 'Aston Martin': 'silver', 'BMW':'blue', 'Bugatti': 'black', 'Hillman': 'green'} export function getBlankCars() { return writable(blank_cars) } export function getCarData() { return writable(raw_cars) } 

What can I do to get the select to display the value?

1 Answer

I think you can reduce the code in Cars.svelte to this REPL - does this function the way you want it to?
Three things to mention

  • if you have an object as store value and want to display the content in an {#each} loop you don't have to generate a new array, but can directly iterate inside each with {#each Object.keys($cars) as car} or {#each Object.entries($cars) as [key, value]}
  • change on:click to on:change={selectCar}
  • the <script> block below the html is unusual ~ the more common order (like in the Svelte tutorial) is script - html - style/css
<script> import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher(); export let cars; let selected_car = 'BMW'; // set default value here function selectCar() { dispatch('message', { value: selected_car }); } </script> <select bind:value={selected_car} on:change={selectCar}> <!-- reduce code by directly iterating $cars via (obj) --> {#each Object.keys($cars) as car} <option value={car}> {car} </option> {/each} </select> 
5

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like