This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-19
Channels
- # aws-lambda (1)
- # bangalore-clj (4)
- # beginners (66)
- # boot (13)
- # cider (9)
- # cljs-dev (44)
- # cljsjs (3)
- # clojure (181)
- # clojure-austin (2)
- # clojure-greece (6)
- # clojure-italy (2)
- # clojure-russia (64)
- # clojure-sg (1)
- # clojure-spec (68)
- # clojure-uk (60)
- # clojurescript (66)
- # conf-proposals (12)
- # cryogen (1)
- # cursive (3)
- # datomic (44)
- # graphql (1)
- # hoplon (2)
- # jobs (2)
- # jobs-discuss (3)
- # keechma (2)
- # liberator (6)
- # luminus (2)
- # nyc (1)
- # off-topic (92)
- # om (10)
- # onyx (17)
- # parinfer (39)
- # pedestal (8)
- # proton (11)
- # re-frame (110)
- # reagent (2)
- # remote-jobs (11)
- # ring-swagger (9)
- # rum (2)
- # sql (2)
- # test-check (6)
- # untangled (138)
Does this pattern have a name in React/Re-frame land? Component A needs data from API endpoint /foo and dispatches an event to fetch it. However, it needs to dispatch an event after that to do its own thing with the data. Same for component B and endpoint /foo but also needs its own event afterwards. Also if the data requested for the same request is already present in the Re-frame db, use that (caching)
@borkdude I don't think that pattern has an official name, but I've taken to calling it "dispatch forwarding", as in, "do your thing and then forward it here"
If I weren't 100% sold on the re-frame way of doing things I'd probably just use CBP instead, with the CB handling the dispatch
Hey all. Is there a nice way to measure the time it takes from a dispatch, a handler changing the db and for reagent to finish rendering components based on the db changes? (in production, without dev-tools)
if I'm creating a form-3 component, do I put my subscriptions outside the reagent/create-class
call or inside the :reagent-render
function as I would for a form-2 component?
Outside, you get some tips in the docs. https://github.com/Day8/re-frame/blob/c2492494a8fa8832f0a170b6bad21fea7e05a521/docs/Using-Stateful-JS-Components.md
perhaps a more pointed question: I need to somehow or another get the width of a component's container into the state for the render function, such that it will re-render on resize. Is there a best practice for doing this?
I've got a plan forming on how to handle this, but if someone has written something up I'd love to see it
About statefull components, you may need need: https://facebook.github.io/react/docs/refs-and-the-dom.html to "initialize".
hi guys
is my understanding correct, that reg-event-fx
should not actually execute any side-effects? and reg-fx
, which supposed to do that, can't return anything else to dispatch?
i can't decide where to put my setTimeout
producing effect, because I need to save the returned value
1- There is a timeout
handler by default on re-frame (but I cant find the name!!)
2- reg-event-fx
functions should return a map that contains:
- :db
- A new, updated (or not) db.
- ~other keys
- Descriptions os side efects (for example, :do-timeout [100 :another-handler]
(reg-fx :my-side-effect-function (fn [[time f]] (js/setTimeout time f))
(reg-event-fx :my-handler (fn [{:keys [db]} [_ param]] {:db (assoc db :waiting? true) :my-side-effect-function [1000 (stuff params)]}))
@valyagolev@souenzzo thanks! but what if i want to capture the return value of js/setTimeout
? as far as i understood from the docs, the reg-fx return is ignored?
@valyagolev you'd have to, in the timeout function, dispatch the value to something else
ah!
so it’s like (reg-fx :hoarding-timeout (fn [[time f]] (dispatch :save-timeout-value (js/setTimeout f time)) ))
in js, setTimeout returns a special value which can be used to remove it
(reg-fx :hoarding-timeout (fn [[time f]] (js/setTimeout #(dispatch :save-timeout-value (f)), time)))
yeah, but i don’t care about it
anyway my problem is solved, thanks, i didn’t realize one could manually dispatch events from reg-fx instead of returning them
np! it was probably not clear from my words, which of the many values involved is actually needed
but well, if i just do it (setTimeout) in reg-event-db
, is it considered low class or dangerous?
@valyagolev no problem. You can write all stuff in reagent... Without "a frame". But if you want to get "the power of re-frame", prefer pure functions
that's very nice
but what i'm asking for is advice on where to put my impure functions. unfortunately i have to use some. and the exact boundaries of pureness are not very clear. we have reg-fx
, reg-event-fx
and reg-event-data
, and i'm wondering which of these require purity of functions, and which don't
event handers should be pure effect handlers are not pure
I'm assuming you store the js/setTimeout
response so you can later remove it
And that removal will be an effect too?
(reg-fx
:clear-alarms
(fn [alarms]
(.cancelLocalNotifications PushNotification (clj->js {:id 1}))
(js/clearTimeout (:timeout alarms))))
(reg-fx
:create-alarms
(fn [date]
(when-not (< date (js/Date.))
(println date (clj->js date))
(.localNotificationSchedule PushNotification (clj->js {:id 1
:message "a pomodoro!"
:date date}))
(rf/dispatch [:save-alarms
{:timeout (js/setTimeout #(rf/dispatch [:alarm-ring]) (- (js/Date.) date))
:notification 1}]))))
here's what i did right now
but i was just wondering if that's the simplest way
there's also
(reg-event-db
:save-alarms
(fn [db [_ alarms]]
(assoc db :alarms alarms)))
and the code which dispatches to :create-alarmsit's three reg-* handlers to handle one logic: 1. ask to create alarms 2. create alarms 3. save their ids
now that i think about it, it's like javascript callbacks all over again...
Checking: so there's only one (:timeout alarms)
at a time?
well, yeah, for now
So two have two options ...
1. You collapse both effect handlers into one
You do clearing and creating in the one effect handler
And you provide the "instruction" (`:clear` or :create
) in the effect itself
ah no, unfortunately there can be either no alarm at all or one alarm
well, it still could work
but the 3-step program to create an alarm is still there
That's fine .... turning on an off the alarm is an effect
So you need to create a small DSL for taking to an alarm manager
Whenever you do an effect you are creating a tiny DSL
So an effect (something returned by an event handler) could be like this ...
{:alarm-manager {:action :create }}
Or
{:alarm-manager {:action :clear}}
Notice that there's now only one effect handler :alarm-manager
. It can maintain whatever state you want
how would it maintain state? using its own atoms inside?
That would work, perhaps like this ...
(def-fx
:alarm-manager
(let [alarm-state (atom)]
(fn [instruction]
(if (= :create (:action instruction))
.....
.....)))
ah i see, that's nice
a question though, why not let def-fx
receive and return :db
as well?
that would collapse the whole thing into something small
Its is tricker than you might initially realise ..
Ordering is a big deal
Which effects get done in what order
At the moment, updating app-db
is not different to any other effect
But suddenly it has to be done last, after all the other effects, so it becomes special
And there are some cases where you might want app-db
writen first
I can't remember the usecases now, but I remember being able to imagine cases like that
yeah, i see
but maybe another way of looking at it would be helpful. the :db handler seem to just do reset!
, right? maybe more swap!
-like logic would really help with cases like that
Yeah, all possible. But I came down on the side of simplicity and giving no guarentees.
That left open the possibility of later on, with more experience, adding guarentees (about ordering etc)
But ... it has never been enough of a problem to move away from what I initially did
another thing i was wondering about re-frame was whether there was a way to dispatch events based on, hmm, some logical relationships between values?
probably an example would be better. say i have a db: {:a 3 :b 4}
, and a variety of events which just do things like inc
and dec
and i have to do something whenever (:a db) = (:b db)
so - very *pseudo*code:
(let [a @(rf/subscribe [:a])
b @(rf/subscribe [:b])]
(if (= a b) (rf/dispatch [:equality!])))
it seems that re-frame could support those things very easily, saving me effort to compare the values in every event
Do many parts of your system change paths [:a]
and [:b]
?
yeah, plenty
Well, i guess the question is; do many event handlers change those paths
yeah, and they change it in different ways
Is it easy to add an interceptor to those event handlers ?
so i could put like a (dispatch [:compare-and-maybe-fire])
everywhere
It kinda sounds like you want a variation on on-change
https://github.com/Day8/re-frame/blob/master/src/re_frame/std_interceptors.cljc#L266
but i think this is a very "declarative" situation, right? so maybe there could be a way to subscribe to all changes to :a or :b
filter them by equality, etc
hmm i'll check it out
thanks!
That's one way of doing it ... add an interceptor to all event handlers which could potentially change those two paths.
That does mean you have to remember to do it (add the interceptor)
it's kind of weird that only the UI code can subscribe to stuff
Which does not deal directly with your need
Back to your need ... you can certainly hack it together ...
(reagent.core/track!
fn []
(let [a @(rf/subscribe [:a])
b @(rf/subscribe [:b])]
(if (= a b) (rf/dispatch [:equality!])))
))
I can't remember the params to track!
off the top of my head ... but something like that
That will permanently be looking at [:a]
and [:b]
If you need to turn the tracking on and off ... you'd have to create an effect to do it :-)
Gotta go. Good luck
haha no, for on-off thing i'd rather do
(reagent.core/track!
fn []
(let [is-tracking-on? @(rf/subscribe [:is-tracking-on])]
a @(rf/subscribe [:a])
b @(rf/subscribe [:b])]
(if (= a b) (rf/dispatch [:equality!])))
))
Well, I'd probably prefer to turn on and off tracking via an effect handler. But yes, what you suggest will work
thanks, good luck. i have some thoughts on the issue you sent, i'll try and send them to you in a bit, we could go on discussing it if you ever have time and interested
I'm interested, but very short on time
Right now. If you have thoughts perhaps open issues or add to them
Then I can cycle back
yeah thanks! i'll see what i can do to make my ideas as useful as possible
I love all input, although sometimes it is hard to find the time to respond effectively
yeah now i think i'll have to read more of the docs to see for which reasons you didn't embrace more reactive approach (as in Elm, etc)
@valyagolev :dispatch-later
is the default fx...