Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Benign cyclical dependencies

Trying svelte for a new project I wrote a component to edit a compound object which delegates editing of individual parts to subcomponent and recreates the compound object whenever a part was changed. Of course, when the compound object is externally changed the subcomponents should be updated to the new values.

I ended up with the following:

<script>  
    let item = "content";
    export let holder = { item };

    $: {
        console.log("setting item to "+holder.item);
        item = holder.item;
    }

    $: setHolder(item);

    function setHolder(i) {
        console.log("setting holder for "+i);
        holder = { item: i }
    }
</script>

<input type="text" bind:value={item} />

The above compiles but the content cannot be edited as somehow when item is edited the first reactive block is executed setting the variable back to holder.item.

I don't understand the following:

  • Why is the first reactive block executed? As item only appears on the left-hand-side of an assignment it is not a value it depends on.
  • Why has the cyclical dependency be "hidden" from the compiler, why doesn't the following work?
    $: {
        console.log("setting item to "+holder.item);
        item = holder.item;
    }

    $: {
        console.log("setting holder for "+item);
        holder = { item }
    }
  • And why does everything work when wrapping both reactive blocks into functions?
    $: setItem(holder)
    function setItem(h) {
        console.log("setting item to "+h.item);
        item = h.item;
    }

    $: setHolder(item);
    function setHolder(i) {
        console.log("setting holder for "+i);
        holder = { item: i }
    }

It seems odd to relying on the compiler somehow not seeing what the code is doing so I'm wondering if I'm having a completly wrong approach.

like image 570
Reto Gmür Avatar asked Oct 20 '25 16:10

Reto Gmür


1 Answers

A reactive statement will re-execute whenever any of the variables mentioned changes. So your first statement will re-run when holder or item changes.

The function approach works, because all of a sudden you only mention one variables (the compiler only looks in the immediate block, not inside any functions that would be called)

I admit it's a bit confusing at first, but hope this makes it a bit clearer

like image 191
Stephane Vanraes Avatar answered Oct 23 '25 15:10

Stephane Vanraes