Morning (or afternoon, or evening) Clojurians.. I’m wondering if someone more advanced can offer a quick suggestion about the best way to dispatch multiple events with reframe. I have event handlers already for two things I want to do on a certain click (reset some ui state and navigate to a new route). What’s the re-frameiest way to write that? My attempts so far include 1. just calling some function that dispatches both events one after the other and 2. a new event handler that looks kind of like:
(rf/reg-event-fx
:composite/event
[validation-interceptor]
(fn [_ _]
{:fx [[:dispatch [:event/one]]
[:dispatch [:event/two]]]}))
is there better way, or a right way to do this, or is it a case of “whatever works”?
Using the :fx
effect like that is definitely the right way to go @kiraemclean
cool, thanks!
if its all :dispatch
there is also :dispatch-n
but I believe :fx
is better
it sounds like that’s exactly what I’m looking for! I didn’t notice anything about :dispatch-n
https://github.com/day8/re-frame/blob/master/docs/api-builtin-effects.md#-dispatch-n
I realize there are probably multiple right ways to do anything, but just curious what’s the “normal” reframe way if there is such a thing.
Was going to mention it, but :dispatch-n
was deprecated in favor of using :fx
with multiple :dispatch
effects
ah I see it’s deprecated in my version anyway. thank you for the reference Josh! I missed it.. totally burnt out on reading docs right now.
appreciate the help 🙏 hope you both have a nice day!
Likewise ☀️
thanks 🙂
@kiraemclean Maybe controversial, but I would avoid dispatching at all
just compose functions that return :db and :fx
managing/testing "what is the state of the app after this event fires" is a hard question otherwise
Hi there. I do an :http-xhrio
to an end point which just delivers text. edn actually!! Now I want my event handler to expect and process edn. Isn't there something like:
:response-format (ajax/edn-response-format)
I just find (ajax/json-request-format...) and :text. Both fail. Where did I turn for Mars? Pls help me return.
@bastilla ajax.edn/edn-response-format
is what you’re looking for 🙂
Awesome! A million thanks! @josh604
No problem. If you’re sending EDN from your backend, you might want to consider using the https://github.com/cognitect/transit-clj format instead. The reason that edn-response-format
is not in the ajax.core namespace is because they deprecated it, as EDN isn’t recommended for sending data to the browser
Ok, good hint. :thumbsup: I'll change it in the long run.
not sure I understand what you mean. how is this different from the above example that returns :fx?
Are there any examples out there of reframe apps that include tests? My struggles are more with getting cljs tests compiling and running than reframe specifically, but reframe is still part of the challenge. I’m wondering if there are any open source examples I can look at.
Also, is anyone successfully using devcards with reframe? I know that’s a bit tricky and I’ve come across several hacks/workarounds to make them play nice with the single global state thing, but no complete implementations. Curious whether anyone has an example of that, too.
So far I’ve just punted it, trying to make view functions pure and use devcards like normal, but it would be cool to be able to use them for more complete views that dispatch events and/or require subscriptions that it wouldn’t make sense to pass in
Haven't delved too deep, but these real-world projects do have some CLJS tests and use re-frame, if my notes are correct: - https://github.com/district0x/memefactory - https://github.com/district0x/name-bazaar
I would be curious about that as well
cool, thank you! looks like they’re using doo for a test runner. interesting to consider.
well, uhh
instead of this
(rf/reg-event-fx
:event/one
(fn [{:keys [db]} _]
{:db (... db ...)
:fx (... fx ...)}))
(rf/reg-event-fx
:event/two
(fn [{:keys [db]} _]
{:db (... db ...)
:fx (... fx ...)}))
(rf/reg-event-fx
:composite/event
[validation-interceptor]
(fn [_ _]
{:fx [[:dispatch [:event/one]]
[:dispatch [:event/two]]]}))
you do this
(defn handler:event-one
[{:keys [db]} _]
{:db (... db ...)
:fx (... fx ...)})
(rf/reg-event-fx
:event/one
handler:event-one)
(defn handler:event-two
[{:keys [db]} _]
{:db (... db ...)
:fx (... fx ...)})
(rf/reg-event-fx
:event/two
handler:event-two)
(defn handler:composite-event
[cofx event]
((compose-handlers
handler:event-one
handler:event-two) cofx event))
(rf/reg-event-fx
:composite/event
[validation-interceptor]
handler:composite-event)
where compose-handlers
threads through the db and concats anything in :fx
generally you don't need compose to work on Handler, Handler -> Handler
, you can have it just work on (db -> {:db, :fx}), (db -> {:db, :fx} -> (db -> {:db, :fx})
if that makes sense
so you might end up with
(defn handler:composite-event
[{:keys [db]} event]
((compose
#(handler:event-one {:db %} event)
#(handler:event-one {:db %} event)) db))
that way you can just call handler:composite-event
in a test and you can see exactly the state the db would be in after an event fires
which is a PITA otherwise