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?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
> 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.
I think this is similar to what you want to achieve: https://github.com/day8/re-frame/blob/master/docs/FAQs/PollADatabaseEvery60.md
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.
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).
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.
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?
What is the exact stacktrace you're seeing?
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)
@p-himik there was not enough space on threads pane, i pasted here
at eval (core.cljs:44)
- isn't it your own core.cljs
?
Also, Slack threads can be expanded to take the fill width. There's always space.
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?
I think it is not difficult considering event handlers and subs needs to be defined in reframe anyway
How does your event handler look?
Try giving that fn
a name to make that name appear in the stacktrace.
Oh thank you now I can see it in the stacktrace. Is it a common practice to give event handler/subs a name?
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.
Ok I think I will see if it is going to be necessary at the end myself