I was trying to loop through and initialize a dictionary based on a prop in svelte but so far it seems impossible. There's gotta be a way to do this right?
<script>
export let max;
let map = {};
$: if(max != undefined){
for(var i=0; i<max; i++){
if(i<5) {
map["id_"+i] = 1;
}
else {
map["id_"+i] = -1;
}
}
}
</script>
<p>{max}</p>
Not sure what exactly was the problem of your version (I'd change to $: if(max) {...}
) (turns out it was using var
instead of let
) but if you put the functionality in the onMount function it works >> REPL
<script>
import Component from './Component.svelte'
</script>
<Component max={20}/>
<script>
import {onMount} from 'svelte'
export let max;
let map = {};
onMount(() => {
for(var i=0; i<max; i++){
if(i<5) {
map["id_"+i] = 1;
}
else {
map["id_"+i] = -1;
}
}
console.log(map)
})
</script>
<p>{max}</p>
Corrl's version works, but has an important caveat: your array won't be updated if you change the max prop on the fly, because the component will not be destroyed & re-mounted, and hence your array routine will not run again.
Perhaps this is your intent, or perhaps it is not.
A reactive version will keep the array updated. However, when dealing with reactive statements, my advice is always to keep these statements as simple as possible.
A cleaner solution to your problem would be to move your array building routine into a simple function that accepts the max
value as input and returns the initialized array:
function makeMap(max) {
const map = {}
for(var i=0; i<max; i++){
if (i<5) {
map["id_"+i] = 1
} else {
map["id_"+i] = -1
}
}
return map
}
Then your reactive code becomes a very simple:
$: map = makeMap(max)
that respects the fundamental reactive assignment rule with the reactive variable (map
) on the left hand side and the dependency (max
) on the right hand side.
Here is a REPL demonstrating the difference between having your array updated through a reactive statement, and having it initialized through onMount
. Have a look at the console while you change the max
prop passed to the component by clicking on the +
button.