Fork me on GitHub

is there a nice way to pass on the result of a subscription? so i could do stuff like (-> (subscribe [:a]) (subscribe [:b with-result-of-a]) (fn [[a b]] {:a a, :b b}))


@arne-clojurians to me it sounds like you want to have layer-3 subscriptions The idea is that you can compose subs that extract some path from db (layer-2) into a “materialized views” (layer-3).


yes, kind of. but layer-3 subscriptions seem to work like 1. run some subscription -> 2. do something with the result of the previous computation. the problem i have is that i need a third step (see above, the subscription running with the result of the previous subscription) where i need the result of the first step as well. at the moment i'm running the first subscription twice which is ok because it's cheap, but it's not very elegant


You can subscribe to the previous step. One moment, I’ll try to make my self clear 🙂


Usually you can arrange your stuff so that you can compose your subs like this

 (fn [db _]
   (:cats db)))

 (fn [db _]
   (:dogs db)))

 :<- [::cats]
 (fn [cats _]
   (map :age cats)))

 :<- [::dogs]
 (fn [dogs _]
   (map :age dogs)))

 :<- [::cat-ages]
 :<- [::dog-ages]
 (fn [[cat-ages dog-ages] _]
   (reduce + (concat cat-ages dog-ages))))


And you can do artibrary computation at any of the steps and subscribe to that data in other subscriptions.


Ahhh now I read your message again and got your point. So you need earlier results further down the chain. Don’t be worried about the performance because intermediate results are cached.


If you need “raw cats” in the last step just subscribe to [::cats]


And now I read it again and I’m not sure if I get what’s the problem. 🙂 But as far as I understand I think you can just split the computation into different subs and subscribe to the intermediate results wherever you need them.


aah i see. you helped me a lot with your explanation, thanks!

👍 1
Simon Brooke14:08:11

Hi guys, I'm having a problem with an on-click handler, I wonder if anyone could help. Essentially I have a GDPR consent form, using signature-pad ( to capture a signature. So when moving on from the form, I need to extract the signature from the signature pad and storing it in the database. I'm setting the on-click handler by setting a map including the key :on-click as the attributes of an element, and I'm logging to the console so I can see the function which sets the attributes is being called. But when I inspect the element, the on-click handler is not present, and when I click the element, nothing happens. Fuller explanation here:!topic/clojure/D2iGl0jkaaM

Simon Brooke14:08:26

Any help exceedingly welcome!


Did you wrap the on-click handler in #(…) as needed? It sounds like the function might be called in page load rather than on click.


are you sure you want #(fn [] ...) and not just (fn [] ...)


Drop the inner fn and try.


Yeah, or (fn []… without #, as above.

Simon Brooke15:08:46

No apparent change. That might be figwheel failing to reload, hang on...

Simon Brooke15:08:14

Doing a clean and rebuild, to be sure, to be sure...

Simon Brooke15:08:47

H'mmm... stepping through in Javascript, it's because that's not actually being called...?!?

Simon Brooke15:08:59

Is there anything magic re-frame does with the value of :on-click keys?


never seen anything unusual, give it a function and it just calls it. It does pass in the on-click event, so maybe add that in as an arg to your handler function?


Hi, anyone had any luck with Microsoft Edge? I'm working with input elements, and need an :on-change handler, but if I include one then typing performance is prohibitively slow, even if the handler is a no-op (It's over 300ms for each button press when I'm emulating a Surface Pro 4, which is a fairly reasonable situation for our target audience). Re-frame-10x says the timing is all "misc", so I'm a little stumped as to what's going on. Any suggestions on how to debug further?


@simon_brooke what do you mean keys? Your own ui helper function just changes :handler key for the on-click. Did you get rid of the doubly nested function?

Simon Brooke16:08:36

OK, I'm not clear what you mean by a double nested function; I've removed the #( and subsituted just (, but that makes no difference.


(ui/big-link "I consent"
             ;; :target (str "#elector/" (:id elector) "/true/")
             :handler (fn
                         [:set-consent-and-page {:elector-id (:id elector)
                                                 :page       :elector
                                                 :elector    (merge elector
note that there isn't a # in front of the fn.


also your merge seems kinda weird. I don't understand what the keyword :signature is supposed to accomplish in the merge


which might explain it. (merge {} :bob :apple) throws an error. is it possible you're throwing an error in the dispatch and not seeing it?

Simon Brooke16:08:52

Yes, that's what I now have. And you're right, that merge should be assoc...

Simon Brooke16:08:55

However, the interesting thing I've found is that if I change :on-click to :alt - and make no other changes, thus:

Simon Brooke16:08:10

(defn big-link [text & {:keys [target handler]}] (js/console.log (str "Big link with target '" target "'; handler '" handler "'")) [:div.big-link-container {:key (gensym "big-link")} [:a.big-link (merge {} (if target {:href target}{}) (if handler {:alt handler}{})) text]])

Simon Brooke16:08:57

I do get the function as alt text, but if I change it back to :on-click, I don't get an on-click handler...


try onClick?

Simon Brooke16:08:19

Yes, confirmed. If I use an attribute name that's invalid, like :froboz, then no attribute is generated. If I use one that's valid but the value would just be text, I get the text of my handler. If I use :style, things go VERY weird; and if I use :on-click, like :froboz, I get nothing...

Simon Brooke16:08:25

OK, so this doesn't work either:

Simon Brooke16:08:40

(ui/big-link "I consent" :handler #(ui/log-and-dispatch [:set-consent-and-page {:elector-id (:id elector) :page :elector :elector (assoc elector :signature (.toDataURL sig-pad "image/svg+xml") )}]))

Simon Brooke16:08:09

(which is presumably the other solution to what you meant by 'double wrapped function').

Simon Brooke16:08:43

:onclick also results in nothing...


one thing i would recommend is not use big-link. just use a simple structure and get it going. then you can diagnose if there's an issue with biglink or your handler

Simon Brooke16:08:23

Yes, that-s a good suggestion.

Simon Brooke16:08:41

OK, so what I currently have is this:

Simon Brooke16:08:43

(defn gdpr-render [] (let [elector @(subscribe [:elector])] [:div [:h1 "I, " (:name elector)] [:div.container {:id "main-container"} [:table [:tbody [:tr [:td [:p "Consent to have data about my voting intention stored by " [:b "Project Hope"] " for use in the current referendum campaign, after which it will be anonymised or deleted."] [:p [:i "If you do not consent, we will store your voting intention only against your electoral district, and not link it to you"]]]] [:tr [:td [:canvas {:id "signature-pad"}]]]]]] (ui/back-link "#dwelling") [:div.big-link-container {:key (gensym "big-link")} [:a.big-link {:on-click #(ui/log-and-dispatch [:set-consent-and-page {:elector-id (:id elector) :page :elector :elector (assoc elector :signature (.toDataURL sig-pad "image/svg+xml") )}])} "I consent"]] (ui/big-link "I DO NOT consent" :target (str "#elector/" (:id elector) "/false"))]))

Simon Brooke16:08:48

No on-click handler is generated, either using the key :on-click or the key :onclick.

Simon Brooke16:08:02

Tried :onClick as well, nothing.

Simon Brooke16:08:25

It also makes no difference if I change from an a tag to a span tag: still no on-click handler with any of :on-click, :onclick or :onClick

Simon Brooke16:08:19

Right, on another page I use :on-click, no 'on-click' attribute shows in the element which you inspect it, but nevertheless the value of the :on-click key is called when the element is clicked. So I think someone's suggestion upthread that my function is being called but is failing silently is probably right....

Simon Brooke16:08:41

Yes, that's correct. When I try [:a.big-link {:on-click #(js/console.log "Hello there") "Froboz"] I get Hello there in the console.

Simon Brooke16:08:53

Thanks everyone, I'm cooking with gas now.

Simon Brooke16:08:29

And the actual error was I was not handling my atom correctly. D'oh!

👍 1

In the docs here, there's an ambiguity (in my head at least) in the explanation of :dispatch-later. When I return the following from an fx handler:

{:dispatch-later [{:ms 200 :dispatch [:foo]}
                  {:ms 100 :dispatch [:bar]}]}
Does [:foo] get dispatched at t+200ms and [:bar] at t+300ms. Or does [:bar] get dispatched first?


To answer my own question, [:bar] gets dispatched first, at t+100ms. The relevant part of the implementation: (set-timeout! #(router/dispatch dispatch) ms)

👍 2