Reagent/re-frame drag event weirdness

492 views
Skip to first unread message

David Pidcock

unread,
Jul 22, 2015, 4:10:27 PM7/22/15
to ClojureScript
I'm playing with Reagent + re-frame (and re-com) for a toy project of mine and I noticed something strange.

I'm creating a component I want to use to drag things around with:

(defn drag-handle
[]
(fn []
[re-com/label :style {:padding "5px"} :label "||"
:attr {:id (:id combatant)
:draggable true
:on-drag-start #(re-frame/dispatch [:drag-start %])
:on-drag (fn [event]
(prn (.clientX event))
(re-frame/dispatch [:drag event]))
}]))


The handler looks like this :
(re-frame/register-handler
:drag
(fn [db [_ event]]
(prn "after dispatch ; " (.-clientX event))

When I use dispatch asynchronously (.-clientX event) is correct when printed from the function attached to the component, but nil when it reaches the handler.

if I use dispatch-sync, the output is consistent.

Is this a bug in re-frame/dispatch router-loop code , or core/async? Or expected behaviour?

I haven't tried this with a vanilla (chan), and I've only tested in Chrome

Could it be that the javascript object isn't "realized" until it has been read, and the mouse event is "dead" after the router-loop executes the (<! (timeout 0)) ? -- I have no idea :D

Another weird thing : on-drag doesn't fire the first time I drag the handle.
on-drag-start does fire, but then I have to "let go" and (without selecting a different object) start dragging again to get the on-drag events flowing. (This might be an artifact of html5's drag implementation -- I may need to go back to mouse-down/up/move)

This also raises the question of whether I should be dispatching the drag events through re-frame's router.

So for those of you with more experience building with these tools, I ask : might it be better to have a special channel to handle drag events (still in app-db, accessible via re-frame/subscribe) which would not need to compete with potentially long-running event handlers?

Colin Yates

unread,
Jul 22, 2015, 4:15:49 PM7/22/15
to clojur...@googlegroups.com

Events use the flyweight pattern and are effectively nil after the callback. Dispatch is async so you need to extract what you need from the event in the callback and pass that into the dispatch.

--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

David Pidcock

unread,
Jul 22, 2015, 4:31:16 PM7/22/15
to ClojureScript
Thank you.
So expected behaviour :D

Quick clarifying question : when you say "Events use the flyweight pattern" do you mean Javascript events themselves, or the Clojurescript event objects that wrap them?

Colin Yates

unread,
Jul 22, 2015, 4:36:10 PM7/22/15
to clojur...@googlegroups.com

Actually I can't find the reference (somewhere in the om wiki?), so I don't know why, but I do know the event is only usable in the callback.  Might be leading you up the garden path wrt the flyweight pattern :).

David Pidcock

unread,
Jul 22, 2015, 4:39:15 PM7/22/15
to ClojureScript

NVM = I answered my own question with some experimentation :D

Javascript events can be passed into a setTimeout function call just fine.

Daniel Kersten

unread,
Jul 22, 2015, 4:55:59 PM7/22/15
to ClojureScript

React refuses the "synthetic" event objects AFAIK.


Reply all
Reply to author
Forward
0 new messages