Fork me on GitHub
#re-frame
<
2018-12-06
>
alexanderjamesking10:12:56

is it an antipattern to use re-frame.core/dispatch inside a subscription? I’d like a component to use a subscription, then inside the subscription to dispatch an event to load some data if it is not present in the DB

oliy08:12:34

hi @alexanderjamesking it may be an antipattern according to the docs but we are still using it extensively and successfully in our apps. i like the way it separates the "data i want" from "how do i get the data i want" (which event do i dispatch etc)

oliy08:12:12

so you can just say "i want this data" and subscribe to it and it's there, without having to pollute the code that needs the data with having to know how to fetch it as well

lmergen11:12:37

@alexanderjamesking i think you will most likely want to use effects here

alexanderjamesking11:12:29

or maybe not: https://github.com/Day8/re-frame/blob/master/docs/FAQs/LoadOnMount.md#extra-for-those-with-redux-backgrounds ‘subscriptions are not imperative. They do not cause things to happen ’

alexanderjamesking11:12:20

so it’s cleaner to dispatch an event to explicitly trigger a load than to do it from inside a subscription

lmergen12:12:27

alternatively, you can also do something like this: https://github.com/Day8/re-frame-forward-events-fx

Whiskas14:12:22

What do you guys use for http requests? :http-xhrio?

Whiskas14:12:57

the right approach would be to make an wrapper event around it and then dispatch this event from another event?

Whiskas14:12:04

like: {:dispatch [:api-post “/users” user-data :on-success-event :on-error-event])} ?

Lu16:12:08

I never wrapped it.. I simply used the examples in the documentation..

(re-frame/reg-event-fx
  ::http-post
  (fn [_world [_ val]]
    {:http-xhrio {:method          :post
                  :uri             ""
                  :params          data
                  :timeout         5000
                  :format          (ajax/json-request-format)
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-success      [::good-post-result]
                  :on-failure      [::bad-post-result]}}))

alexanderjamesking16:12:20

@mateus.pimentel.w I use cljs-http and do something very similar to what you suggested with :on-success and :on-error event handlers. If you want a nice abstraction over http that includes re-frame event handlers for you look at https://github.com/oliyh/martian

👍 2
genekim18:12:51

Holy smokes — I’m embarrassed that I’ve spent 5+ hours on this problem, but I’ve finally narrowed it down to a surprising conclusion… Can anyone help me figure out how to solve this problem? I was using https://github.com/metosin/komponentit/blob/master/src/cljs/komponentit/clipboard.cljs to copy text into the clipboard. It works terrific… but only when Google Closure compiler optimization is turned off. When optimization is turned on, the clipboard always remains unchanged. [insert lots of investigation] Mysteriously, the execCommand("copy") always returns false and fails to copy text to the clipboard when Closure advanced optimization is turned on. I even resorted to writing it purely in JavaScript, as per https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f, and using js interop to call that function. And even when the execCommand in pure JavaScript, when called from a CLJS program that has been Closure optimized, it fails. Is there something I need to call that would enable execCommand("copy") to work in an CLJS/Closure optimized program? Many thanks in advance for helping me regain my sanity!!!! 🙂

genekim19:12:43

PS: @thheller wrote: >>> @genekim works fine for me. does your :advanced build maybe change something else that changes the semantics of the call? I think copy is only allowed as the result of a user event. so it can’t be done via setTimeout or so IIRC (edited)

genekim19:12:59

Which made me start wondering if it’s “re-frame related”? I call the execCommand("copy") inside of an event handler… oh… hang on… it’s called in an event handler that it called asynchronously… ahh… (maybe I need to call it synchronously, so that it’s in a user-event?) …trying now…

genekim19:12:02

OMG. @thheller It worked! Wow! THANK YOU!!!! You’re so fantastic! (And you were fabulous in the defn and REPL podcasts. :)

👍 1
genekim19:12:27

For posterity for anyone else facing the same problem: it was because execCommand("cut") was called from an event handler that was called through re-frame/dispatch. Solution was to change it to re-frame/dispatch-sync, to preserve the context of the user event. Whew. (I weep that I spent so much time on this… But OTOH, I learned a lot about JS interop, the DOM, and the minor miracle that is the browser…)

Braden Shepherdson19:12:53

we perennially have the same trouble on mobile, where the keyboard pops up when focusing an input element only when you call myInput.focus() from inside a user event handler.

genekim19:12:35

I spent hours reading about what’s allowed and not allowed in the browser and what DOM and system modifications you’re allowed to do. Wow. It’s really complicated. 🙂

lwhorton20:12:24

the dom is fundamentally one of the most difficult apis i’ve ever had to work with, and yet its prevalent across mostly everything 😦