Looping
{#each}
block allows you to loop only array or array-like object (i.e. it has a .length
property).
Here are some examples if you want to loop through data structures besides array.
Looping a map
You can use spread operator [...value]
for Map to get an array of key value pairs.
<script>
const map = new Map([
['.svelte', 'Svelte'],
['.js', 'JavaScript']
]);
</script>
{#each [...map] as [key, value]}
<div>
{key}: {value}
</div>
{/each}
Both Map.keys()
and Map.values()
method return an iterable. To use {#each}
with iterable, you can use spread operator [...value]
on the iterable.
<script>
const map = new Map([
['.svelte', 'Svelte'],
['.js', 'JavaScript']
]);
</script>
{#each [...map.keys()] as key}
<div>
{key}
</div>
{/each}
{#each [...map.values()] as value}
<div>
{value}
</div>
{/each}
Looping a set
You can use spread operator [...value]
for Set to get an array of items.
<script>
const set = new Set(['.svelte', '.js']);
</script>
{#each [...set] as item}
<div>
{item}
</div>
{/each}
Looping a string
String is considered an array-like object as it has .length
property.
<script>
const string = 'Svelte';
</script>
{#each string as character}
<div>
{character}
</div>
{/each}
Looping a generator function
Generator function function*
returns a generator object, which conforms to both the iterable protocol and the iterator protocol.
To use {#each}
with generator function, you can use spread operator [...value]
on the generator.
<script>
function* generator() {
yield '.svelte';
yield '.js';
}
</script>
{#each [...generator()] as item}
<div>
{item}
</div>
{/each}
Binding to a spread item
Once you spread a Map, Set, Generator, or any Iterable, you are creating a new array, and therefore binding (bind:
) with the item may not work anymore.
<script>
const map = new Map([
['.svelte', 'Svelte'],
['.js', 'JavaScript']
]);
</script>
{#each [...map] as [key, value]}
<!-- You can't change the value of the input, nor the value in the map -->
<input bind:value />
{/each}
To workaround this, you can use on:input
listener
<script>
const map = new Map([
['.svelte', 'Svelte'],
['.js', 'JavaScript']
]);
</script>
{#each [...map] as [key, value]}
<input
{value}
on:input={(event) => {
map.set(key, event.currentTarget.value);
map = map;
}}
/>
{/each}