Fork me on GitHub
#re-frame
<
2021-04-08
>
Stuart08:04:53

I'm a bit confused by effectful handlers in re-frame and reg-fx, mainly how I should get a value back from a reg-fx and into my app-db. Say I wanted to start a timer using js/setInterval, this returns a handle that I need to get into app-db so I can stop the timer later. But I'm not sure how I get this handle back... My re-agent

[:button.btn.btn-secondary.reset
       {:on-click #(rf/dispatch [:toggle])}
       "toggle"]
I want to toggle the timer on / off when I click the button, so I dispatch [:toggle] I have a reg-event-fx
(rf/reg-event-fx
 :toggle
 (fn [cofx _]
   (let [new-ticking (not (:ticking (:db cofx)))]
     {:db (assoc (:db cofx) :ticking new-ticking)
      :toggle-ticker [new-ticking (:db :ticker-handle)]})))
Then I have my reg-fx for :ticker-handle
:toggle-ticker
 (fn [[ticking handle]]
   (if ticking
     (js/setInterval dispatch-timer-event 1000);; How do i get the handle returned by this javascript into my app-db ???
     (js/clearInterval handle))));; Effect handler return values are ignored...
^^^^ How can I get the handle that (js/setInterval ,,,) returns? And my dispatch-timer-event function, which I just want to dispatch a :tick event.
(defn dispatch-timer-event []
  (rf/dispatch [:tick]))
Am I approaching this all wrong?

p-himik09:04:34

> how I should get a value back from a reg-fx and into my app-db. Call (dispatch [:some-event-that-writes-to-db]). If you want some state but don't really need app-db for that, then just use a separate atom and reset! or swap! it in the effect handler.

Stuart09:04:32

Thank you! That seems obvious now you say it, I think I was overthinking this!

lassemaatta09:04:51

I vaguely remember using coeffects sometimes when I need to provide some state from effects (e.g. from local storage, or timers) to event handlers and don't want to "cache" it in the app-db (or just want to make a clear separation between the data in the app-db and data elsewhere).

Stuart08:04:59

I guess I could just do the setInterval in the event handler but the docs advise against this.

Stuart09:04:15

And I'm trying to understand side-effects handling

Stuart09:04:35

Oh great! I hadn't found that in the docs. Yeah, that looks exactly it.

Umur Gedik20:04:06

Hello, I’m new to clojurescript and the tooling around it. In one of my event handlers I’ve made a mistake and every time I dispatch the event an error is thrown. But stacktrace shown in the browser console all about library internals. I believe my setup doesn’t work as it should have.

Umur Gedik20:04:09

This is ther error message Uncaught Error: Vector's key for assoc must be a number. and at the moment I know which event handler is causing the problem because I only have 3 handlers 🙂 but imagining this scenario in a medium sized project I would very difficult time to figure out what is the problem. Do you think this is because of my setup or something? Do you get better error messages when one of your event handlers are problematic?

p-himik20:04:20

What is the exact stacktrace you're seeing?

Umur Gedik20:04:57

router.cljc:204 Uncaught Error: Vector's key for assoc must be a number.
    at Object.eval [as cljs$core$IAssociative$_assoc$arity$3] (core.cljs:5621)
    at Function.eval [as cljs$core$IFn$_invoke$arity$3] (core.cljs:2002)
    at Function.eval [as cljs$core$IFn$_invoke$arity$3] (core.cljs:5330)
    at Function.eval [as cljs$core$IFn$_invoke$arity$3] (core.cljs:5330)
    at eval (core.cljs:44)
    at eval (std_interceptors.cljc:100)
    at re_frame$std_interceptors$db_handler__GT_interceptor_$_db_handler_before (std_interceptors.cljc:100)
    at Object.re_frame$interceptor$invoke_interceptor_fn [as invoke_interceptor_fn] (interceptor.cljc:70)
    at Object.re_frame$interceptor$invoke_interceptors [as invoke_interceptors] (interceptor.cljc:108)
    at Object.re_frame$interceptor$execute [as execute] (interceptor.cljc:201)

Umur Gedik20:04:29

@p-himik there was not enough space on threads pane, i pasted here

p-himik20:04:33

at eval (core.cljs:44) - isn't it your own core.cljs?

p-himik20:04:53

Also, Slack threads can be expanded to take the fill width. There's always space.

Umur Gedik20:04:13

Oh yes that is the line my bad. Is there any way to get the information like function names get printed on the stack trace whenever these kind of errors happens?

p-himik20:04:40

How does your event handler look?

p-himik20:04:19

Try giving that fn a name to make that name appear in the stacktrace.

Umur Gedik20:04:44

Oh thank you now I can see it in the stacktrace. Is it a common practice to give event handler/subs a name?

p-himik20:04:47

Can't talk for others, but I almost never do it. I'm lazy and I find issues quickly given even an obscure stacktrace - naming such functions just isn't worth it for me. Reagent definitely recommends somewhere in its documentation to name inner view functions exactly for that reason. I couldn't find anything in the re-frame documentation. Feel free to create an issue if you think it will be useful.

Umur Gedik20:04:10

Ok I think I will see if it is going to be necessary at the end myself

👍 3
jahson06:04:16

It's a good practice that helps to find issues easier with only one big downside: the need to name things. But it is really helpful sometimes.

Umur Gedik11:04:50

I think it is not difficult considering event handlers and subs needs to be defined in reframe anyway