How to catch a button click and execute server & client Electric code without an e/Token? My issue with e/Token token is that if I consume the token with (t), it seems to interrupt any in-flight server code (that isn't offloaded). Maybe I'm doing something wrong here:
(when-some [t (dom/button (dom/text "New Order")
(let [e (dom/On "click" identity nil)
[t err] (e/Token e)]
t))]
(let [order-id (e/server (create-order! conn seller-id))] ; this returns an id.
(r/Navigate! ['/ ['Orders order-id]])
(t))) ;; consuming token here breaks r/Navigate! because it interrupts the when-some.
whereas it works if I take out the (t), but it feels like I'm leaking memory.
(dom/on "click" (fn [] clojure-only) nil)) <= how to run e/server or e/client code on click?yes you def are leaking memory if you don't dispose the token
the point of the token is to deal with failure, latency, retry, so the sequence of effects here should be • button click, construct token • query server, render busy state, wait for result • check server result for success or failure • if failure: don't navigate, use token to inject error back into the button so user can try again • if success: navigate
> it seems to interrupt any in-flight server code (that isn't offloaded) this i don't understand
Oh, (t) doesn't have any causal dependency on the server result order-id, that's why
(case order-id ::success (r/Navigate!), ::failure (t err))
Thanks, that works! Lotta people dumber than even me are gonna have a hard time with that. I sort of know how Electric works and spent an hour trying to figure out how I was using r/Navigate! wrong, until I accidentally took out the token consumption. We are not very wired for the implicit asynchronicity.
btw. is there a way to keep track of unconsumed tokens? Guaranteed this is gonna be a big source of memory leaks.
git gud, sorry
I do miss just being able to pass an e/fn to a dom/on "click" event
we will probably add try/catch at some point which will help make this more natural looking
it's almost like Electric needs its own async IDE
you can implement a backwards compatible API that uses "callbacks", but we just think it has too many problems, we certainly don't want to encourage buggy patterns
"deez purple codes will run at same time" (hard, I know)
like rainbow parens for async-executing lines would be cool. I would have spotted that independent (t) instantly
well, it's all async, every expression is maximally concurrent
do body is concurrently running every expression, I guess that's what got you?
Re leaks - wrap your token fn in a timeout, something like
(e/defn TimeoutToken [nm ms t]
(when t
(case (e/Task (m/sleep ms))
(do
(prn 'leak nm)
(t))))
t)The token API is less glamorous for the easy case, we agree on that. But it brings immense benefits wrt composition
> is there a way to keep track of unconsumed tokens if you're correctly monitoring the token to render busy and failure states (as in the https://electric.hyperfiddle.net/tutorial/token_explainer), it will be very obvious that the token is undisposed because your button will be yellow