Fork me on GitHub
#re-frame
<
2019-11-25
>
johanatan18:11:48

does anybody know what could cause a reg-event-fx or a reg-event-db handler to get a many to many channel as its db value ?

p-himik18:11:44

Some effect handler returns the channel as DB?

p-himik18:11:55

re-frame by itself doesn't use channels, so it's most likely an issue with your own code.

johanatan18:11:06

The effect handler in this case is the http-xhrio. You provide an on-successand an on-failure and it calls you back on one of them.

johanatan18:11:28

Perhaps yes something went wrong with my specification of on-failure or on-success

p-himik18:11:35

Sorry, I meant event handler.

johanatan18:11:43

Yea, sorry, I did too

johanatan18:11:57

Actually no it is an effect in this case

p-himik18:11:13

Can you show the code?

p-himik18:11:50

For the event handler where you use the http-xhrio effect.

johanatan18:11:07

I have several layers of wrappers. Would be too complicated to show. But I think you've helped me isolate it to those wrappers

p-himik18:11:14

One of the wrappers probably returns the channel within an event handler that's registered with reg-event-db. Small advice: add an interceptor to all your event handlers that check your DB against some spec. Makes debugging so much more simpler. No problem.

johanatan18:11:57

Basically the result is coming back in to an event handler which then does: {:dispatch (conj [::original-event] result)}

johanatan18:11:12

but that dispatched event should get the cofx (or db) inserted automatically by re-frame no ?

johanatan18:11:26

i.e., i don't need to explicitly thread the cofx (or db) through

p-himik18:11:41

Yes. It means that the error happens some place else. Most likely, somewhere earlier.

p-himik18:11:43

I hope you don't have code like:

(reg-event-db :my-cool-event
  (fn [_ _]
    (do-stuff)))
🙂

johanatan18:11:54

what's wrong with that code?

johanatan18:11:14

should be fx instead of db ?

p-himik18:11:49

If do-stuff just returns a new DB and does nothing else, then all is good! Event handlers must not have side effects.

johanatan18:11:29

oh, i bet that's the problem

p-himik18:11:31

If you want to have a side effect, create an effect handler and return the effect from one of the event handlers that you've registered with reg-event-fx.

johanatan18:11:37

i have a db handler that doesn't return a db

johanatan18:11:43

yep, good call

johanatan18:11:48

let me look in to that

johanatan18:11:02

i remember having this problem once before

p-himik18:11:09

Returning nil is not fine as well - your DB will just become nil.

johanatan18:11:13

once one reg-event-db returns a non-db, then that becomes the db from there on out!

p-himik18:11:26

That's why I mentioned having a global interceptor that validates stuff. 🙂

p-himik18:11:44

kee-frame has a built-in support for it, for example, because it's such a good practice.

johanatan18:11:49

Do you have an example of that interceptor?

johanatan18:11:50

found the culprit:

+  (rf/reg-event-db
+   ::init-base-data
+   [(rf/inject-cofx ::inject/sub [:state.core/timerange])]
+   (fn-traced [{:keys [state.core/timerange]} _]
+              (reset! route-matrix/*state (assoc-in route-matrix/initial-state
+                                                    [:filters :group-by]
+                                                    (if (app-config-service/get-supports-routes?)
+                                                      "Route" "Path")))
+              (reset! route-matrix/*on-redraw (.. js/ChartUtils -donutcharts -onRedraw))
+              (reset! route-matrix/*timerange timerange)
+              (route-matrix/init!)
+              (reset! route-matrix/*poll (async/poll! init!))))

johanatan18:11:24

(this code is halfway in an old-world state and is being re-frameized incrementally)

johanatan18:11:49

async/poll! returns a many to many channel

p-himik18:11:41

And you must not have reset! within event handlers.

johanatan18:11:50

Yes, I am aware

p-himik18:11:04

BTW what's ::inject/sub?

johanatan18:11:27

[vimsical.re-frame.cofx.inject :as inject]

p-himik18:11:49

Ah, right.

johanatan18:11:50

so... this is the "fix":

(rf/reg-event-fx
   ::init-base-data
   [(rf/inject-cofx ::inject/sub [:state.core/timerange])]
   (fn-traced [{:keys [state.core/timerange]} _]
              {:state.core/callback
               (fn []
                 (reset! route-matrix/*state (assoc-in route-matrix/initial-state
                                                       [:filters :group-by]
                                                       (if (app-config-service/get-supports-routes?)
                                                         "Route" "Path")))
                 (reset! route-matrix/*on-redraw chart-utils/donut-chart-on-redraw)
                 (reset! route-matrix/*timerange timerange)
                 (route-matrix/init!)
                 (reset! route-matrix/*poll (async/poll! init!)))}))

johanatan18:11:10

where :state.core/callback is reg'd as an fx handler which calls the function.

p-himik18:11:03

Not an ideal solution but definitely better than it was before. 🙂

johanatan18:11:22

yea, like i said "incremental improvements" here. the codebase is in a state of flux

johanatan18:11:27

while being modernized