Fork me on GitHub
#re-frame
<
2016-10-14
>
josh.freckleton02:10:01

I just adapted the previous snippet from a yogthos blog, but it's still a bit laggy.... any advice?

josh.freckleton02:10:25

it's a bit better because it only updates state locally until a less frequent push to global is needed, but it's still a bit slow

josh.freckleton02:10:24

It seems like this is a valid enough problem that others could benefit from a more permanent answer, so I just posted a couple options, and the main question on SO: http://stackoverflow.com/questions/40034152/how-do-i-handle-input-elements-in-clojure-re-frame

mikethompson03:10:16

We don't see laggyness

mikethompson03:10:12

For example: http://re-demo.s3-website-ap-southeast-2.amazonaws.com/#/input-text Your code looks okay. So I'm not sure what is going on

josh.freckleton03:10:54

@mikethompson huh, ya, yours is quicker... mine is definitely lagging...

superstructor03:10:24

do you have any interceptors/middleware @josh.freckleton ? e.g running with debug interceptor makes things noticeably laggy. what kind of code are you running the handler on change, just assoc-in or similar ?

josh.freckleton03:10:53

@superstructor there are no interceptors on this feature, and the handler just assocs to db... pretty simple, I'm just trying to get an "MVP" of an input text box going!

josh.freckleton03:10:09

(MVP - "minimum viable product")

mikethompson04:10:43

I really don't know much about with-let, so I'm suspicious of that. Does this work better:

(defn text-input
  "adapted from:
  

  The big idea is this holds local state, and pushes it to the global
  state only when necessary"
  [{:keys [sub-path disp placeholder]}]
  (let  [value    (r/atom nil)
          focused? (r/atom false)]
    (fn []
     [:input
      {:type      :text
       :on-focus  #(do (reset! value @(subscribe sub-path))
                       (reset! focused? true))
       :on-blur   #(do (dispatch (conj disp @value))
                       (reset! focused? false))
       :value     (if @focused? @value @(subscribe sub-path))
       :on-change #(reset! value (-> % .-target .-value))
       :placeholder placeholder}])))

mikethompson04:10:56

Hmm. I'm not sure my translation is 100% right, but you get the idea.

nfisher11:10:59

I’ve found dispatch has issues on an input field.

nfisher11:10:15

And dispatch-sync seems to solve them.

si1412:10:30

@mikethompson can I humbly ask you to take a look at https://clojurians.slack.com/archives/re-frame/p1476351307003620 if you have some time? Feels like it's one of the last things that I'm not entirely familiar with in re-frame :)

si1412:10:21

@nfisher thanks for the post you've linked! One small question: why do you use dispatch-sync in the last example?

si1412:10:46

ah, I see: >use dispatch-sync for input fields to prevent an unusual user experience (e.g. unexpected resetting of cursor position). very interesting point! I wonder what's "official" position on this

nfisher12:10:42

@si14 I’ve found in apps with 10s of components it becomes a bit of a problem in input fields. To reproduce you can insert your cursor in the middle of input values delete some characters and start typing. On occasion it will bounce the cursor to the end position rather than the current position within the field.

nfisher12:10:34

It could be related to the nesting of components I have but I did notice it with vanilla ReactJS+Redux as well.

lxsameer16:10:08

I have a ul element which will appear with a Jquery SlideDown effect when user clicked on a link. How can I model this behavior in re-frame ?

josh.freckleton16:10:52

@nfisher thanks I'll check that out! does that result in any speed up? Or just synchronizes dispatches?

nfisher16:10:11

dispatch an event - it will be handled sometime AFTER the current handler completes. dispatch-sync an event - it will be handled immediately, before the current handler completes.

nfisher16:10:03

If I have time I’ll try to create an isolated test case that reproduces it.

josh.freckleton17:10:20

@nfisher thanks, i'm checking it out! At first glance dispatch-sync really seems to help! @lxsameer I know re-com has a dropdown: http://re-demo.s3-website-ap-southeast-2.amazonaws.com/#/dropdown also, bootstrap works well, and I'm sure you could get jquery going too!

lxsameer17:10:38

@josh.freckleton I want to know how, can I do it using coeffects ?

lxsameer17:10:45

what is the best practice here ?

josh.freckleton18:10:45

How would you use coeffects? I understand how it could be viewed as an effect, in which case you'd dispatch a command to drop down, I'm not sure I understand your usage tho...

lxsameer18:10:12

@josh.freckleton dispatch an event, return a coeffect in event handler and in the interceptor to the jquery stuff

lxsameer18:10:28

@shaun-mahood I already read that, but honestly I can't figure out where in that schema, event handlers live ?

shaun-mahood18:10:39

@lxsameer: Ok, I'll take a quick look at jQuery slidedown (it's been a while) and see if I have any ideas.

lxsameer18:10:04

@shaun-mahood dude, let me put it this way

lxsameer18:10:30

where should I do my dom manipulation based on events, in the re-frame data flow

shaun-mahood18:10:43

@lxsameer: I prefer to start by having a specific fx event that does it for me - once I have everything working I then take a look and see if that particular event makes sense to become an interceptor or something else. Just typing up a quick example.

shaun-mahood18:10:50

@lxsameer

(re-frame/reg-fx
  :jquery/slidedown
  (fn [dom-id]
    (re-frame/dispatch [:jquery/slidedown-fx dom-id])
    {}))

(re-frame/reg-event-fx
  :jquery/slidedown-fx
  (fn [{:keys [db]} [_ dom-id]]
    ;; Do your DOM manipulation here if it's a function call
    { :db db ;; or return changes to the DB here if it is done in a subscription
     }))

shaun-mahood18:10:46

If you want to change that to an interceptor later it's not very difficult

shaun-mahood18:10:54

But I've never actually used this to do what you want to do, so it's quite possible that it won't work at all for your use case - but hopefully it gives you another starting place

lwhorton19:10:55

heya guys, am I being dumb wrt to the newer reg-sub syntax and the sugar :<-? if I provide a form-1 reg-sub (provide a function that returns input signals) or a form-2 reg-sub (provide some :<- [:some/sub] sugar), it seems that db is no longer the first argument passed to the computation function?

lwhorton19:10:21

which means that if I still want access to the full db inside of the second function, I have to create some subscription that simply returns the full db? is there a way to not have to do this, but always be given the full db + any sugar’d input signals?

lwhorton19:10:15

or more plainly:

(reframe/reg-sub
  :foo
  (fn [db]
    {:bar (bar/find-thing db)
     :baz (subscribe [:baz])}))

vs.

(reframe/reg-sub
  :foo
  (fn []
    (subscribe [:baz]))

  (fn [[baz]]
    {:bar (bar/find-thing ???) ;; where did db go :(
     :baz baz}))

mikethompson20:10:35

Do you need something like this?

(reframe/reg-sub
  :a-thing
  (fn [db]
    (find-thing db)))

(reframe/reg-sub
  :foo
  :<-  [:baz]    ;; or write as (fn [_ _]  (subscribe [:baz]))
  (fn [baz _]
    baz])) 


(reframe/reg-sub
  :uses-both-the-above
  (fn [_ _]
     [(subscribe [:a-thing]) (subscribe [:foo])]
  (fn [[thing foo] _]
    ...))

mikethompson20:10:16

The last one above could also have been written:

(reframe/reg-sub
  :uses-both-the-above
  :<- [:a-thing]
  :<- [:foo]
  (fn [[thing foo] _]
    ...))

mikethompson20:10:57

@lwhorton ^^^ see two examples above

lwhorton20:10:15

thanks @mikethompson, that confirms what I thought about how things work. I wanted to avoid making a reg-sub for particular data pieces, but it seems that’s idiomatic.

lwhorton21:10:23

while I’m on the topic, is there something I need to be doing with namespaces to ensure ns A which has reg-sub :foo :<- [bar] can still reference ns B which has reg-sub :bar (fn [db] (:bar db)?

lwhorton21:10:02

I’m getting an re-frame: no subscription handler registered for: “ :bar”. Returning a nil subscription error, and was wondering if it’s simply a loading-order issue?

mikethompson21:10:48

@lwhorton I suspect it is a "never loaded" issue

mikethompson21:10:44

Make sure that some central namespace is requiring B, to pull it in