Skip to content

Instantly share code, notes, and snippets.

@bowbahdoe
Created July 9, 2021 22:32
Show Gist options
  • Save bowbahdoe/7fd8714cd910d43eb3229f967d95cbc6 to your computer and use it in GitHub Desktop.
Save bowbahdoe/7fd8714cd910d43eb3229f967d95cbc6 to your computer and use it in GitHub Desktop.
lilactown Today at 5:22 PM
I remember someone in this channel talking about constructing effects data using function chaining; who was that? tell me your secrets again :stuck_out_tongue:
32 replies
p-himik 1 hour ago
If I understand you correctly, it was probably @emccue
emccue 1 hour ago
@lilactown refresh my memory a bit?
emccue 1 hour ago
I think i know what you are asking for, but i want to make sure before i go off
lilactown 1 hour ago
something about how you organize your events/effects, where instead of writing the effects in an event as data you use helper functions to construct the effects:
(rf/reg-event-fx
::something
(fn [{:keys [db]} [_ foo bar]]
(-> (do-thing {} foo)
(do-another-thing bar)
(do-one-last-thing))))
(edited)
emccue 43 minutes ago
yeah so the first bit is every event handler is a reg-event-fx for consistency
emccue 42 minutes ago
and we only ever return :db and :fx
emccue 42 minutes ago
for :fx, we have namespaces dedicated to them that look basically like this
emccue 41 minutes ago
(rf/reg-fx
::alert
(fn [contents]
(js/alert contents)))
(defn alert [contents]
[[::alert contents]])
(defn alert-uppercase [contents]
(alert (string/upper-case contents)))
emccue 40 minutes ago
so each "effect" is a function you call that returns a vector of vectors
emccue 40 minutes ago
{:fx (alert "abc")}
emccue 40 minutes ago
and if you want to combine fx, we have a helper function that concats them together
emccue 39 minutes ago
{:fx (fx/in-order
(alert "abc")
(http-req {...}))}
(edited)
emccue 38 minutes ago
then if we have some process that we want to re-use in multiple handlers that will update state and perform some effects, we make a function
emccue 38 minutes ago
(defn do-thing [db]
{:db (inc db}
:fx (alert-fx/alert "abc")})
emccue 37 minutes ago
and we have another helper that lets us compose functions that have the signature db -> {:db, :fx}
emccue 36 minutes ago
(rf/reg-event-fx
::abc
(fn [{:keys [db]} [_ abc]]
(let [process (compose-effect-fns
do-thing
(fn [db] {:db (* db 2)}))]
(process db))))
(edited)
emccue 32 minutes ago
and for new stuff we aren't allowing dispatches within a handler - keeping dispatches to only stuff the user did or reactions to outside processes
emccue 32 minutes ago
beyond that nowadays its gotten to
emccue 31 minutes ago
(defevent abc
[a b c]
:handler
(fn [{:keys [db]}]
{:db (* db a b c)
:fx (alert-fx/alert "AAA")}))
lilactown 31 minutes ago
how do you handle like, "do a network request and then update the app-db"?
emccue 30 minutes ago
which produces a constant event:abc equal to ::abc , a function abc, which when called will produce a vector you dispatch and a function handler:abc which is your re-frame handler
emccue 30 minutes ago
do you mean app-db updates you do as soon as you launch the request or when it comes back
emccue 22 minutes ago
(defevent successfully-did-thing
[response]
:handler
(fn [{:keys [db]}]
{:db (* db 2)}))
(defevent failed-to-do-thing
[error]
:handler
(fn [{:keys [db]}]
{:db (/ db 5)}))
(defevent do-thing
[user-id]
:handler
(fn [{:keys [db]}]
{:db (+ db 1)
:fx (http-fx/request
{:uri "..."
:params {... user-id ... }
:on-success successfully-did-thing
:on-failure failed-to-do-thing})}))
emccue 22 minutes ago
(we re-wrote the normal :http-xhrio to support some stuff like functions for on-success, but same concept)
emccue 18 minutes ago
does that make sense?
:+1::skin-tone-2:
1
p-himik 16 minutes ago
@emccue That's at least the third time I see how you write extensively on this topic.
Have you considered making a blog post or at least a detailed gist about it? Would be easier to share, publicly improve upon, and discuss in a persistent manner that's not possible on this Slack.
emccue 12 minutes ago
eh? its a pattern we still haven't worked out all the issues with and are using as a tool to patch up a large codebase. The ideal end point might be a library other than re-frame because it explicitly goes against what I think is intended design
emccue 12 minutes ago
plus its literally just the way elm does stuff being forced onto re-frame - not without reason, but certainly without elegance
emccue 11 minutes ago
but yeah next time it comes up I'll try to make a gist
:+1::+1::skin-tone-2:
2
emccue 7 minutes ago
also i don't have a blog to put it on - i know that makes me a heretic
lilactown 4 minutes ago
a gist or something durable would be great for me! thanks for taking the time to write this down
lilactown 3 minutes ago
bouncing around meetings rn but I will digest and maybe ask a couple more qs in a bit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment