re-frame

Stefano 2024-02-20T09:41:06.723299Z

Hello everyone! I have a question on what would be the best approach to handle this situation in re-frame. Let's say I have this:

(rf/reg-event-fx 
 :event-0
 {:dispatch-n [[:event-1] 
               [:event-2]]})
And that :event-1 further dispatches other events via :dispatch-n, for example:
(rf/reg-event-fx 
 :event-1
 {:dispatch-n [[:event-1-0] 
               [:event-1-1] 
               [:event-1-2]]})
Is there any way to dispatch :event-2 after all or some of the other events have been handled? The options I explored so far are: 1. Dispatch another event in the :event-1 handler (or its "children") only to notify that the event has been handled. 2. Use rf/add-post-event-callback (maybe wrapped in a reg-fx) to dispatch :event-2 after one or more of the events have been handled. 3. Poll the db until some condition is met. All of these have trade offs and I am wondering if there are other better options. I would really appreciate any suggestion. Thanks!

p-himik 2024-02-20T09:50:28.752429Z

The most robust and simple solution would be to avoid "util" events and instead compose functions that receive and return fx.

Stefano 2024-02-20T09:58:08.599489Z

Umh, seems interesting. Are you able to provide an example? Let's say :event-1 doesn't know about :event-2 . How that would look like?

wevrem 2024-02-20T15:11:31.608779Z

Note that :dispatch-n is deprecated. If :event-1 doesn’t know about something, but needs to dispatch it, then it needs to be provided with it, for example, as an argument.

(rf/reg-event-fx
 :event-0
 (fn [{:keys [_db]} _]
   (let [event-for-after [:event-2 arg1 arg2]]
     {:fx [[:dispatch [:event-1 event-for-after]]]})))

(rf/reg-event-fx
 :event-1
 (fn [{:keys [_db]} [_ event-for-after]]
   {:fx [[:dispatch [:event-1-0]]
         [:dispatch [:event-1-1]]
         [:dispatch [:event-1-2]]
         [:dispatch event-for-after]]}))
Or you could stash :event-2 in app/db.
(rf/reg-event-fx
 :event-0
 (fn [{:keys [db]} _]
   {:db (assoc db :event-for-after [:event-2 arg1 arg2])
    :fx [[:dispatch [:event-1]]]}))

(rf/reg-event-fx
 :event-1
 (fn [{:keys [db]} _]
   (let [{:keys [event-for-after]} db]
     {:db (dissoc db :event-for-after)
      :fx [[:dispatch [:event-1-0]]
           [:dispatch [:event-1-1]]
           [:dispatch [:event-1-2]]
           [:dispatch event-for-after]]})))

p-himik 2024-02-20T19:47:20.903879Z

When one event doesn't know about the other but needs to dispatch it and also rely on a particular problem makes it sound like you're trying to make the problem harder than it needs to be. :) For each involved event, use only reg-event-fx and extract the handler as a separate defn. Instead of dispatching events from event handlers, call their handlers directly. Also, FWIW when you do need to dispatch multiple events from an event handler, I definitely prefer dispatch-n over fx+dispatch. I couldn't care less that it's deprecated. :) If such an effect wouldn't have been built into re-frame, I'd create it myself. Fx is still useful of course, but not as frequently.