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

Bug: Unsubscribe not called for synced observable #396

Open
kruczy opened this issue Nov 14, 2024 · 6 comments
Open

Bug: Unsubscribe not called for synced observable #396

kruczy opened this issue Nov 14, 2024 · 6 comments

Comments

@kruczy
Copy link

kruczy commented Nov 14, 2024

Hi 👋

I am trying to integrate 3rd party subscription into legend observable, I need to know when the data is observed to make sure I can manage the other subscription accordingly, tho I saw unsubscribe is never called for my case.

Below is a simple repro unsubscribe log is never called (running 3.0.0-beta.17):

const syncedObservable = observable(
	synced({
		get: () => 'foo',
		subscribe: () => {
			console.log('subscribe');

			return () => console.log('unsubscribe');
		},
	})
);

const Observer = observer(() => {
	return <Text>{syncedObservable.get()}</Text>;
});

const Root = () => {
	const [show, setShow] = useState(false);

	useEffect(() => {
		const interval = setInterval(() => setShow((show) => !show), 2000);

		return () => clearInterval(interval);
	}, []);

	return show ? <Observer /> : null;
};

Unsubscribe is called if I use useObservable(synced directly, tho it does not really satisfy my case.

Thanks
Great lib btw 🔥

@jmeistrich
Copy link
Contributor

Ah interesting! It's supposed to unsubscribe when no longer observed. So I'll look into that. I have a feeling it may be caused by strict mode. I'll let you know.

@kruczy
Copy link
Author

kruczy commented Nov 20, 2024

Hey :)
Thanks for looking into it, I am actually not using strict mode if that helps with debugging. Ill try to create an example outside of react if that is possible 🤔

@kruczy
Copy link
Author

kruczy commented Nov 20, 2024

ok here is an out of react example:

const syncedObservable = observable(
	synced({
		get: () => 'foo',
		subscribe: () => {
			console.log('subscribe');

			return () => console.log('unsubscribe');
		},
	})
);

const unsubscribe = observe(() => {
	console.log(syncedObservable.get());
});

setTimeout(unsubscribe, 500);

@jmeistrich
Copy link
Contributor

Hmm, I think maybe the issue is that stopping observing does not (currently) immediately call the unsubscribe function. On the next update it will see that it's not currently being observed and then call unsubscribe. So I think if you set it to something after unsubscribing you'll see that "unsubscribe" log.

But I can see how that's not the ideal behavior! I'll see if I can improve that.

@kruczy
Copy link
Author

kruczy commented Nov 29, 2024

That does not appear to make a difference unless I understood it wrong but I tried 2 things:

  • call the update function that is passed in subscribe call
  • calling syncedObservable.set(..)

in both cases value updates while subscribed correctly but if called after unsubscription happened does not call the unsubscription callback

@jmeistrich
Copy link
Contributor

Ok, I'll look into it more and get back to you.

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