This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-22
Channels
- # announcements (2)
- # babashka (18)
- # beginners (87)
- # calva (22)
- # chlorine-clover (5)
- # cider (11)
- # clj-kondo (10)
- # clojure (71)
- # clojure-austin (1)
- # clojure-norway (6)
- # clojure-uk (13)
- # clojurescript (3)
- # core-async (10)
- # data-science (17)
- # datascript (1)
- # datomic (22)
- # emacs (10)
- # fulcro (32)
- # hoplon (8)
- # jobs-discuss (2)
- # malli (5)
- # meander (5)
- # nrepl (35)
- # off-topic (8)
- # pathom (38)
- # planck (21)
- # re-frame (10)
- # reagent (17)
- # reitit (7)
- # shadow-cljs (26)
- # tools-deps (3)
- # xtdb (7)
What would be the re-frame way of enforcing updates based on the result of a calculation, not data itself changing. Let's say I have a date in my app-db
: {:started-at (js/Date.)}
and I want to display time passed from the started-at
Is there a way to form a subscription that as an input takes a calculation: (- (js/Date.) started-at)
? Is that a good idea at all? If I wanted to make the UI truly react to data changes, I could create a handler that changes writes to :ms-passed ...
every second, and subscribe to that - would that be a route and why?
An alternative would be force updates of a component every second and do the calculations in the component itself, but that is limiting and hacky.
(defn ticking-component
"Updates every second."
[f]
(let [!interval (atom nil)]
(r/create-class
{:component-did-mount (fn [this]
(reset! !interval
(js/setInterval #(r/force-update this true) 1000)))
:component-will-unmount #(js/clearInterval @!interval)
:reagent-render f})))
(defn time-passed [started-at]
[ticking-component (fn []
(- (js/Date.) started-at))])
If you consider current time a part of your application state, then store it in the DB. If not, then just compute the delta in the components.
That's the puzzle I'm having. I do not consider it a part of my data - I think the started-at
is everything I need to calculate all the UI needs. However I have quite a few places where the result of that calculation is used, which means if I keep it in the UI then I move a lot of logic there. Ideally, I'd be able to create subscriptions based on the calculated time passed.
> then I move a lot of logic there
Personally, I wouldn't consider this "a lot" or even "logic". A matter of taste, perhaps.
This calculation that you need is just a simple (x) -> x
function, akin to inc
for example. Would you want to create a sub specifically to avoid using inc
in a view?
Subscriptions are cached functions of the application state. If something is not a state, don't use a sub for that.
Although I guess that (x) -> x
can be viewed as (x, x) -> x
if you make it referentially transparent so it accepts the current time as one of the arguments. Doesn't really change the reasoning though.
Hmm, I can also force re-calculation of a subscription by passing an arbitraty argument (ie (js/Date.)
) from that hacky ticking-component above.
@U0C10BTPA I do something similar by creating a subscription for the current time that updates on some set cadence. https://gist.github.com/knubie/a031b3db6ad7afb25d91732b3bc76a4d
Very cool @UFJCSRT2M - thanks for sharing