This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-14
Channels
- # announcements (3)
- # babashka (189)
- # beginners (157)
- # calva (5)
- # cider (5)
- # clj-kondo (7)
- # cljdoc (34)
- # clojure (61)
- # clojure-dev (2)
- # clojure-europe (42)
- # clojure-nl (15)
- # clojure-poland (1)
- # clojure-spec (5)
- # clojure-uk (6)
- # clojured (2)
- # clojurescript (31)
- # clojureverse-ops (8)
- # component (2)
- # cursive (41)
- # datomic (15)
- # depstar (44)
- # figwheel-main (9)
- # fulcro (14)
- # holy-lambda (1)
- # inf-clojure (13)
- # introduce-yourself (1)
- # jobs (1)
- # lsp (98)
- # malli (12)
- # off-topic (12)
- # pedestal (1)
- # polylith (3)
- # re-frame (51)
- # reitit (4)
- # releases (1)
- # reveal (5)
- # shadow-cljs (3)
- # tools-deps (56)
- # vim (12)
- # xtdb (36)
Hello, I was looking at https://github.com/day8/re-frame-http-fx#optional-handler-for-on-request and realised that keyword examples are ::http-post
is it a standard to have ::
for events in re-frame?
If you are in namespace blah
then ::kw
is shorthand for :blah/kw
So it is a bit of syntactic sugar from Clojure
And, yes, re-frame keywords for events, subscriptions etc, are often namespaced
Also if you have [foo.bar :as bar]
in your require, then ::bar/baz
will expand to :foo.bar/baz
you can just evaluate those keywords in the repl. it'll expand to the full de-sugared form
Has there been any discussion to allowing :fx handlers to take many args? Seems like an easy thing to accommodate... https://gist.github.com/olivergeorge/a149956af8d137372a954603da15d3e2
It would then work differently from using effects as is, no?
{:effect [1 2]}
will call its handler with a single argument [1 2]
.
I think it's reasonable to expect that {:fx [[:effect [1 2]]]}
will do the same.
@U055DUUFS what @U2FRKM4TW says ... plus it feels your suggestion feels like it is trying to take me back to "positional args" for functions which is something I've been learning alowly not to do ... don't drag me back down that path - it has taken me long enough to learn not to :-)
hahaha
fair call. i think we're all better off with the slightly more verbose arg map.
simple vs easy and all that
How should I approach dispatching multiple events in re-frame? Say for example I want to dispatch an event to query the database and an event to change a page when clicking a button? I understand they can be on the same event as :db
and :http-chrio
<- should this be the approach that I should take?
I wouldn't be sending an event to change the page. In general one event handler should be "calling" over event handlers. And event models something that the user does (or an external agent). The "handler" for that event should itself implement the necessary effects (including page changes) and not "send further events". So, in my opinion, you'll want your event handler to change the state in db, to indicate the change in page, and then have the UI reactively update (because the UI is just a rendering of state).
> I wouldn't be sending an event to change the page.
> In general one event handler should be "calling" over event handlers.
What about being able to reuse already set interceptors on some event? Reusing just the handler won't reuse them, whereas :dispatch
will.
Perhaps we had this discussion before, but I can't recall...
Yeah, I'm definitely a believer that the common code (for changing pages?) should be factored out into a function and not an event handler (with convenient interceptors). Then the event handler can be implemented as a composition of functions - one of which looks after changing pages.
I wish i had more time to put together some docs on this, justifying what I'm asserting (without much evidence). But ... no time currently. Complicated life.
Maybe such docs would convert me as well. :) So far, reusing events is just way too comfortable given interceptors reuse along with an automatic and more granular instrumentation with re-frame-10x. But also, I will probably notice issues in such an approach myself if I ever stumble upon them in my workflow.
Ie. the control flow is confusing?
Not really, for two reasons: • Events that are reused are rarely dispatched in batches by multiple different events, so just linear event tracing in re-frame-10x already gives an almost perfectly clear picture • I'm rather quick at understanding situations when the above is not the case - at least, enough to not notice it introducing any friction. There are patterns that often help me determine event chain immediately, and also each traced event has its fx map in re-frame-10x during development and in a logging service in production, so the worst case scenario is just clicking a few times, maybe entering an event name in the search panel Of course, having something like event originator would improve the situation a bit - but not nearly enough for me personally to even start thinking about how this could be implemented.
I remember being lost in control flow only in one particular kind of scenario - back when I was working for a company that wrote JS+Java enterprise software, it was JS spaghetti with a heavy use of anonymous callbacks mixed in with promises, without any sort of tracing.
@U2FRKM4TW For context, all my rants have been the result of living in a codebase that had events that dispatched to other events
idk what loc you've gotten up to, but for us it got to the point that re-frame-10x was almost useless with the number of "events" that triggered
A very common one was having a "helper event" that set a loading flag in the db and sent off an http request
go to a single page and the event log would have something like 10 http-request-with-loading
and a maybe 20+ set-specific-domain-model
handling the results
and we • Lost stack traces - how did we get to this error? • Couldn't tell from a callsite whether it was a db event or one that could do a side effect • Had bugs because we weren't keeping good enough track of when state changes happened. Events being a queue and normal function calls being a stack meant that our expectations were often totally opposite reality • Basically couldn't unit-test simple stuff like "if we click this button, will the db be updated like so" or "if we click this button, will we send an http request" since it might be (and often was) deep within a "helper event"
idk what benefit you are getting from interceptors - but for us it was mostly telemetry stuff. That fit in with just having a reusable fx
> Couldn't tell from a callsite whether it was a db event or one that could do a side effect Isn't it the case for your current approach as well? How do you make that distinction?
its the case at an initial dispatch site - an event can do both - but it was an issue when events were helpers to other events
we would have a situation where :A would transform the db db -> db'
and :B would just do a side effect and :C would require db'
to do db' -> db''
:A would be named "set-thing" and B and C would be more generically named since they didn't just set - but the fact that they did set was an implicit dependency of other events
@U2FRKM4TW Another issue i'm reminding myself of working through a cruftier part of the code - Using logic to determine which events to dispatch is absolutely cursed
you have a condition there that will determine what to dispatch, but what the event is only loosely related to what is going to happen with the state or the side effects
Now, you might want to write a function to update the state for a page change.
It might take db
as an arg and it might produce a new db
, maybe.
And, in your event handler, you might want to call this function.
But, IMO, you should not send a message to cause a page change.
(from another event handler)