Describe the bug
When using object destructuring assignment to extract 2 stores out of an object, like this:
let store1
let store2
({
store1,
store2,
} = context);
, then only whichever store is assigned to a variable _first_ (in this case store1) can be used. The other one is undefined when you (auto)subscribe to it ($store2).
To Reproduce
I have tried many variations to try to identify which factors are necessary and sufficient conditions for this strange behavior to occur. The 1 broken behavior and various variations that seem to work fine are summarized in this REPL repro.
It appears that this strange behavior — $store2 being undefined (see Broken.svelte) — only occurs iff all of these conditions are true:
AssignWithoutDestructure1.svelte)$store1 at all (see OnlyReferenceStore2.svelte)let instead of const (see Const.svelte)store1 first (see AssignStore2First.svelte)Why exactly can I not use this combination of factors in my Svelte component? What is the rule that I am breaking, and where is it documented?
Expected behavior
I expect to be able to use let and destructuring assignment with store objects just the same as I can with any other type of value.
This works just fine, for example:
let store1
let store2
({
store1,
store2,
} = {store1: 'value1', store2: 'value2'});
// store1 => "value1"
// store2 => "value2"
so I don't think there's anything wrong with my JavaScript. So what is so special about _stores_ as values that would make it not work? And why does let vs. const make a difference here? Is the Svelte compiler doing something special with lets (even though I'm not using $: here) that is causing this strange behavior?
Severity
It seems medium severe to me. I can _probably_ work around it (I will attempt that next), but it certainly diminishes my confidence in Svelte when:
undefined for no apparent reasonMaybe I'm just doing something wrong, but I couldn't figure it out (after hours of turning this into a simple as possible repro), so I reported this as a bug until proven otherwise... :)
In the first broken example, the compiler is outputting
let store1;
$$subscribe_store1();
let store2;
$$subscribe_store2();
$$subscribe_store1({ store1, store2 } = context);
which is incorrect - as opposed to the example without destructuring, where it is outputting
let store1;
$$subscribe_store1();
let store2;
$$subscribe_store2();
$$subscribe_store1(store1 = context.store1);
$$subscribe_store2(store2 = context.store2);
We need to make sure _both_ subscription functions are called after the destructuring assignment happens. So we can continue to use the destructuring in the output, probably what makes them most sense is to make two separate subscription calls afterwards.
This is fixed in 3.25.1 - https://svelte.dev/repl/ba980bfbd031448b8f49500f5900f305?version=3.25.1