Fork me on GitHub
#re-frame
<
2020-12-27
>
datran05:12:29

Does anybody else find themselves wanting a :dispatch-many sort of fx? I often want to dispatch multiple effects in response to a single event, and I don't want to couple them all together in a chain.

datran05:12:37

Something like this:

(defn dispatch-many
  [events]
  (doseq [event events]
    (rf/dispatch event)))

(rf/reg-fx ::dispatch-many dispatch-many)

(rf/reg-event-fx
  ::dispatch-many
  [rf/debug]
  (fn [_ [_ & dispatches]]
    {::dispatch-many dispatches}))

datran05:12:50

Is this a bad smell, or does everyone do this?

p-himik05:12:59

The fx already exists, and it's called :dispatch-n. But combining multiple events into one by wrapping them is definitely a code smell. Move such combinations into a separate event with a specific name.

datran05:12:08

Cool that it already exists! I'll have to compare implementations. Could you elaborate more on the smell? I often have multiple side effects that I want to trigger, all independent of each other. It seems to me I either dispatch them all in response to the trigger event, or I chain them all together where one calls the next. I'm wary of coupling them in that sort of artificial order.

datran05:12:55

Here's an example of how I'm using it now: once a user has authenticated, I need to fetch some more stuff and take care of some state management stuff.

(rf/dispatch [::util/dispatch-many
                              (auth/set-auth (:auth-success state))
                              (app.evt/get-capabilities)
                              (app.evt/sync)
                              (form.evt/destroy-form app.const/authentication-form-id)])

p-himik06:12:13

> Could you elaborate more on the smell? Re-frame documentation does it much better than I ever could.

p-himik06:12:53

> I'm wary of coupling them in that sort of artificial order. Combining them in a new event handler does not couple them in any way.

p-himik06:12:09

An intent should be expressed with a single dispatch with a relevant ID and handler. "Dispatch many" is not the intent in your example above. The intent is to finalize the process of user authentication, or something like that.

datran06:12:53

Ah, I see what you're saying. The event dispatched should be semantically interesting and describable, and you can dispatch as much as you want from inside the event handler.

datran06:12:07

Also, I went to the docs and found this:

From v1.1.0 onwards, this effect is deprecated in favour of using :fx with multiple :dispatch tuples.

datran06:12:32

There's a whole bunch of goodies there that are new in 1.1.0, so I'm glad you pointed me there

👍 3
tobias07:12:16

The only time I write a dispatch many effect is when I use the https://github.com/day8/re-frame-async-flow-fx library and I want to start multiple initial events at the beginning of the flow