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

       {:on-click #(rf/dispatch [:toggle])}
I want to toggle the timer on / off when I click the button, so I dispatch [:toggle] I have a reg-event-fx
 (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
 (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?


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


And I'm trying to understand side-effects handling

p-himik 2021-04-08T09:03:34.130300Z

> 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.

lassemaatta 2021-04-08T09:03:46.130500Z

I think this is similar to what you want to achieve:


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


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

lassemaatta 2021-04-08T09:16:51.132100Z

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).

Umur Gedik 2021-04-08T20:09:06.135Z

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 Gedik 2021-04-08T20:11:09.137100Z

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-himik 2021-04-08T20:12:20.137200Z

What is the exact stacktrace you're seeing?

Umur Gedik 2021-04-08T20:13:57.137600Z

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 Gedik 2021-04-08T20:14:29.138300Z

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

p-himik 2021-04-08T20:14:33.138500Z

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

p-himik 2021-04-08T20:14:53.139100Z

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

Umur Gedik 2021-04-08T20:16:13.140500Z

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?

Umur Gedik 2021-04-09T11:36:50.153500Z

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

p-himik 2021-04-08T20:20:40.140700Z

How does your event handler look?

Umur Gedik 2021-04-08T20:22:31.141Z

Umur Gedik 2021-04-08T20:23:15.141400Z

p-himik 2021-04-08T20:25:19.141900Z

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

Umur Gedik 2021-04-08T20:29:44.142300Z

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

p-himik 2021-04-08T20:34:47.142500Z

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 Gedik 2021-04-08T20:37:10.142700Z

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