This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-19
Channels
- # bangalore-clj (35)
- # beginners (42)
- # boot (89)
- # cider (9)
- # clara (2)
- # cljs-dev (29)
- # cljsjs (3)
- # cljsrn (14)
- # clojars (9)
- # clojure (332)
- # clojure-brasil (1)
- # clojure-dev (5)
- # clojure-italy (4)
- # clojure-russia (36)
- # clojure-spec (38)
- # clojure-uk (65)
- # clojurescript (114)
- # clr (11)
- # community-development (105)
- # core-async (10)
- # cursive (4)
- # datascript (1)
- # datomic (58)
- # defnpodcast (3)
- # emacs (4)
- # hoplon (7)
- # juxt (3)
- # keechma (8)
- # off-topic (7)
- # om (109)
- # om-next (8)
- # onyx (26)
- # pedestal (3)
- # planck (8)
- # re-frame (76)
- # reagent (28)
- # rum (25)
- # spacemacs (2)
- # specter (35)
- # untangled (31)
- # yada (27)
Is there in re-frame something like: I have events x and y but they must also trigger event z? like for example, I want to dismiss an error message when someone hits a button, touches the menu, etc
@borkdude might be a good case for an reusable interceptor
Each event which should trigger a further z
can be wrapped in that interceptor
so the event handlers for x
and y
would have this interceptor (which dispatches a z
)
(def dispatch-z
(->interceptor
:id :trigger-z
:after (fn [context]
(update-in context [:effects :dispatch-n] conj [:z]))))
Note:
1. We are conj
-ing to the :dispatch-n
effect (which is standard)And then we add this interceptor to the event handlers for x
and y
(reg-event-db
:x
[ dispatch-z .... ] ;; <---- interceptor added here
(fn [db event]
.....))
*reg-event-db
@reefersleep thanks, corrected
🙂 And just for completeness (though I suspect @mikethompson's example makes more sense in this case), you could dispatch z
within a reg-event-fx
rather than a reg-event-db
if you only want to do it a couple of places and don't care about the neat reuseability of a vector (EDIT: interceptor), as explained in Step 1 Of Plan
here: https://github.com/Day8/re-frame/blob/master/docs/EffectfulHandlers.md @borkdude
Indeed. So if you didn't want a reusable interceptor, you can manually return the dispatch effect:
(reg-event-fx ;; now using -fx
:x ;; no longer has an interceptor, we're doing it manually below
(fn [{db :db} event] ;; first parameter is now the coeffects, not just db
{:db (assoc db :do :something)
:dispatch [:z]})) ;; here we go ... dispatch that :z event
Note: there are a few standard effects :dispatch
:dispatch-n
:dispatch-later
and, soon, :dispatch-debounce
Directly above I'm using :dispatch
for simplicity, but in the interceptor further above I used :dispatch-n
because I can always safely conj
onto that, no matter what the event handler returns
in general is it better to have flat app-db structure or with nested maps?
with flat structure key names become long
@yury.solovyov: Since re-frame abstracts away the db handling fns from your components, I find that since you no longer have a need for the db shape to match the components, you can do whatever you find most comfortable. I prefer nested maps for the same reason you do. Also, nested maps makes much more sense in our team's state viewer component, where they can be folded in and out at will 🙂 So we can zoom in on the pertinent area.
I was just following python zen "Flat is better than nested"
maybe blindly though
In many cases, that surely applies.
Is there anything against writing:
(reg-event-db :x
(fn [db _]
(dispatch [:z])
(assoc db …)
I think this is mentioned in docs https://github.com/Day8/re-frame/blob/master/docs/EffectfulHandlers.md#90-solution
I think this is done via vector
dispatch [:do-something-else 3]
will dispatch [:do-something-else 3 :and-more 42]
work?
me too, just guessing
@borkdude here https://github.com/Day8/re-frame/blob/master/docs/Effects.md#dispatch-n
Hey fellow clojurians, i have a question. I have a subscription on a list of item and when i build the List, i have two input fields to create a tag for the list entry. If i create an Event will be sent to the backend and add a tag to the entry. Problem is, the frontend will not rerender obviously, because nothing on the list subscription changed. Any ideal how to Update the changed entry in the List, in Order Not to reload the whole list?
@dev-hartmann: Welcome! Are you able to share the code that's giving you problems? In general, you will have to have something that is able to see that there has been a change in order to update, so either a new subscription, an additional change that your event makes, a new event, or something else along those lines.
is there a way to perform more that one update to db for :db effect?
like :db (assoc db :foo 42) (assoc db :bar 1)
maybe via merge somehow?
@yury.solovyov: You should be able to use the thread-first macro (https://clojuredocs.org/clojure.core/-%3E) and do
:db (-> db
(assoc :foo 42)
(assoc :bar 1))
yeah, look nicer than (assoc db panel (merge (panel db) {:updating true :current-path new-path}))
That's a pattern I used a ton in pre-0.8.0 but I haven't tested it yet that exact way, so let me know if it doesn't work.
yup, works, thanks
Oh good
@yury.solovyov you can use update there: (update db :panel merge {:updating true :current-path new-path})
@snoe thanks, yeah, that's an option too
Hi, I have a layout change (i.e., new DOM elements inserted shifting existing ones down) triggered by some atom's data changing (suppose a new section added to a page). I also have mouseenter and mouseleave event handlers setup on individual elements. If said layout change results in a change to which element is underlying the current mouse pointer, then my effects in the mouse handlers (which do typical "highlight color" stuff) do not run for the new element under the cursor (or for the old element under the previous relative cursor position for that matter).
If you "leave" the element and "enter" again it would work right ?
But then I'd have an awful lot of stateful stuff going on: i.e., querying the system for the location of the mouse pointer (only under this particular type of re-render) and then triggering events manually
[i've added an :on-mouse-over and that mostly handles it: but i still need the mouse to move one pixel to really get back up to date]
[i.e., without :on-mouse-over, the mouse/user has to exit the panel completely and then go back into it (or another panel)]
ok I understand
Hmm, actually i guess i could just query the system for the element under the cursor and allow that to override my atom's storing the values for whether an element is hovered or not (at the start of the render cycle)
and playing with keys so it's not rendered again could help ?
well, if the mouse moved out of the element as a result of the new insertions, it would need to be rendered again
and i doubt that react + :keys would consider mouse position when determining if it should re-render
this just seems like such a common scenario that i figured that others would've come up with some standard solution (as it would be a problem for any React app-- not just reframe/reagent)
Yes indeed
never encountered this but thats interesting
i guess for now i'm ok with the "one pixel move" requirement (as we are in MVP stage only at this point 🙂 )
I dont have any other idea right now, let's wait for other people to read
normally i'd try to use CSS for this but it was being very finicky hence my resorting to manual on-mouse-enter and on-mouse-leave
Do you have the same pb with css ?
ho ok
no, different problem. couldn't even get it to work at all (even without the re-layout complexity)
i think it had to do with wanting to change descendant properties from ancestor's :hover
[although that should be possible-- it's complicated. there was one other complicating factor i forget at the moment]
sorry, that may not all be exact: but it was definitely some combination of two factors along similar lines like that
Thought some of you might find this useful. It's a collection of utility/syntactic sugar functions for re-frame I find myself using in a lot of re-frame projects https://github.com/nikolap/reframe-utils