go to REPL here: https://svelte.dev/repl/27a2cff81ebb4000970eee32747cc6c2?version=3.20.1
open the console
uncomment line 27 ($: canSubscribe && $store)
Expected:
I thought that the $store can subscribe (with the $:) only if canSubscribe is true.
The question is: Why $store subscribe if canSubscribe is false?
Am I wrong?
I need it because in my real project I'm using https://github.com/timhall/svelte-apollo and I can do this:
$: canRender && $books.then(data => {... here I use Svelte reactivity to watch for some variables...})
But I need to wait for canRender before subscribe $books.
Svelte subscribes to autosubscriptions once when the component is created, unsubscribes/resubscribes if the value assigned to the store variable itself changes, and unsubscribes when the component is destroyed. This is more efficient and easier to reason about then trying to do some short circuiting stuff with expressions like that.
Somewhat recently, it was decided to make autosubscribing to null or undefined valid, and for it to not do anything, meaning the variable holding the autosubscribed value would be undefined.
I don't think any of this behavior is something we want to change, but it should be documented more clearly somewhere, perhaps in the eventually appearing 'deep dive into how reactivity works' write-up.
Yes please, some docs needed.
Somewhat recently, it was decided to make autosubscribing to null or undefined valid, and for it to not do anything, meaning the variable holding the autosubscribed value would be undefined.
Can you please explain this better with an example?
The change was in #4304 and was to resolve #2181.
just faced this by myself and got kinda confused about how did it work. I have a condition when (or if) observable should be subscribed or not, the workaround I did to write two conditions in two places (template & script) to do so and I'm not sure if it's the best way to do it though. is there any better way to do it so that it will only subscribe when I want to?
i.e.:
<script>
import { interval } from 'rxjs';
import { startWith } from 'rxjs/operators';
let count = 0;
let store$ = interval(500).pipe(
startWith(0),
);
// first condition
$: cond = count > 2;
$: proxyStore$ = cond ? store$ : null;
</script>
<h1>count: {count}</h1>
<!-- second condition here, the same one -->
<!-- if I remove this condition, it displays "undefined" -->
{#if cond}
<p>{$proxyStore$}</p> <!-- this depends on the condition -->
<p>{$store$}</p> <!-- this is subscribed automatically -->
{/if}
<button on:click={() => count++}>
Click Me
</button>
EDIT: this one might be related: https://github.com/sveltejs/svelte/issues/4929
Most helpful comment
Svelte subscribes to autosubscriptions once when the component is created, unsubscribes/resubscribes if the value assigned to the store variable itself changes, and unsubscribes when the component is destroyed. This is more efficient and easier to reason about then trying to do some short circuiting stuff with expressions like that.
Somewhat recently, it was decided to make autosubscribing to
nullorundefinedvalid, and for it to not do anything, meaning the variable holding the autosubscribed value would be undefined.I don't think any of this behavior is something we want to change, but it should be documented more clearly somewhere, perhaps in the eventually appearing 'deep dive into how reactivity works' write-up.