Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stores / observables can't be used as reactive declarations #2579

Closed
cdock1029 opened this issue Apr 26, 2019 · 4 comments
Closed

stores / observables can't be used as reactive declarations #2579

cdock1029 opened this issue Apr 26, 2019 · 4 comments

Comments

@cdock1029
Copy link

See: https://svelte.dev/repl?version=3.1.0&gist=478580926063e8de3e4dec7908d40e9e

Simple example, de-referencing either of these results in undefined

$: rx = of(['x','y','z'])

$: store = writable(['store'])
{#each $rx as r}
<p>{r}</p>
{/each}

{#each $store as s}
<p>{s}</p>
{/each}
@cdock1029
Copy link
Author

cdock1029 commented Apr 26, 2019

https://svelte.dev/repl?version=3.1.0&gist=b9ddf1ae922f198847f0434e15511764

let storeVar = writable(2);
let localBoolVar = true;
$: reactiveVar = localBoolVar ? "was true" : "was false";
$: reactiveStoreVar = localBoolVar ? writable(5) : writable(6);

compiles to:

function instance($$self, $$props, $$invalidate) {
	let $storeVar, $reactiveStoreVar, $$unsubscribe_reactiveStoreVar = noop, $$subscribe_reactiveStoreVar = () => { $$unsubscribe_reactiveStoreVar(); $$unsubscribe_reactiveStoreVar = reactiveStoreVar.subscribe($$value => { $reactiveStoreVar = $$value; $$invalidate('$reactiveStoreVar', $reactiveStoreVar); }) };

	$$self.$$.on_destroy.push(() => $$unsubscribe_reactiveStoreVar());

	let localBoolVar = true;
	let storeVar = writable(2); subscribe($$self, storeVar, $$value => { $storeVar = $$value; $$invalidate('$storeVar', $storeVar) });

	function click_handler() {
		const $$result = localBoolVar = !localBoolVar;
		$$invalidate('localBoolVar', localBoolVar);
		return $$result;
	}

	let reactiveStoreVar;
	$$self.$$.update = ($$dirty = { localBoolVar: 1 }) => {
		if ($$dirty.localBoolVar) { $$invalidate('reactiveStoreVar', reactiveStoreVar = localBoolVar ? writable(5) : writable(6)); }
	};

	return {
		localBoolVar,
		storeVar,
		reactiveStoreVar,
		$storeVar,
		$reactiveStoreVar,
		click_handler
	};
}

*edit: fixed this example

@cdock1029
Copy link
Author

I think this is a pretty good mitigation. Basically the use case is dynamically updating observables. Having to recreate them which implicitly requires unsubscribing and resubscribing is probably not the best pattern anyways.

https://svelte.dev/repl?version=3.1.0&gist=76a7ff3ce9a96750b936c300fe0180e5

(From the discussion here ReactiveX/rxjs#4740 (comment))

@kylecordes
Copy link

What's the use case for code like this? It seems to me that someone handling their dataflow with RxJS is probably on a path toward learning to use a nailed up observable chain (with switchMap where needed, to create new observables based on old ones emitting). Mixing RxJS with the “$:” syntax to re-create observables reactively seems much harder to reason about than either part (Svelte reactivity, and RX just) separately. But I am probably missing something in the intention of the code.

@cdock1029
Copy link
Author

cdock1029 commented Apr 27, 2019

Well the use case was to use autosubscribe in templates while also being able to update the source of data. Until I saw the issue for modifying BehaviorSubject api linked above, I didn't see a way to have that observable chain update with changes to bind:value={$someSourceObservable$}.

Shorter: "deriving" data from other data, seamlessly. I have another issue relating to this goal here that describes how svelte derived stores don't quite get us there #2553

But I think BehaviorSubject w/ fix for setting does, and I agree with your point that going all in on rxjs is the way to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants