re-frame

https://github.com/Day8/re-frame/blob/master/docs/README.md https://github.com/Day8/re-frame/blob/master/docs/External-Resources.md
unwarysage 2021-04-24T23:48:59.336Z

Hello, starting out in re-frame and liking it. I'm trying to move beyond the simplest stuff, and am trying to figure out how to write my first interceptor/coeffect. I'm writing a little dice-rolling app, and I want to abstract out the randomness into an effect. Assuming for a moment I have a working reg-cofx'ed add-roll-info, I am trying to now setup the reg-event-fx call. But how would I access which roll I'm wanting to get random numbers for in the (inject-cofx :add-roll-info {:the "map or roll-id to look up to produce the map"}) ?

p-himik 2021-04-25T09:20:05.336200Z

I'm not sure what you're asking exactly, but have you seen this documentation section and the ones below it? http://day8.github.io/re-frame/Coeffects/#meet-reg-cofx

emccue 2021-04-25T17:37:41.336500Z

(rf/reg-fx 
  ::generate-random-number
  [when-done]
  (rf/dispatch-sync
    (when-done (Math/random))))

(rf/reg-event-fx
  ::got-random-number
  [{:keys [db]} [_ x]
  {:db (assoc db :x x)}) ;; pick something better than :x, hopefully something scoped

(rf/reg-event-fx
  ::clicked-dice-roll-button
  [{:keys [db]} _]
  {:fx [[::generate-random-number (fn [x] [::got-random-number x])]]})

emccue 2021-04-25T17:41:42.336700Z

at least to me reg-cofx makes sense for getting the current time - if you were to add a :tick event to your model that would become cumbersome and it is a benefit of being in an impure language that you can make a practical decision like that

emccue 2021-04-25T17:42:40.336900Z

but anything else I either try to build out from effect managers I already wrote or in really rare cases add make a new effect manager

emccue 2021-04-25T17:44:10.337200Z

like lets say you wrote that effect manager above, it generates a random number between 0 and 1, just the fundamental randomness

emccue 2021-04-25T17:44:55.337400Z

(ns your.project.effects.random)

(rf/reg-fx 
  ::generate-random-number
  [when-done]
  (rf/dispatch-sync
    (when-done (Math/random))))

(defn generate-random-number [when-done]
  [[::generate-random-number when-done]])

emccue 2021-04-25T17:45:27.337600Z

first I would move the effect to a namespace and expose a function that returns something you can put in :fx to do it

emccue 2021-04-25T17:45:36.337800Z

so you would use it like this

emccue 2021-04-25T17:46:39.338Z

(ns ...
  (:require [your.project.effects.random :as random-fx]))

(rf/reg-event-fx
  ::clicked-dice-roll-button
  [{:keys [db]} _]
  {:fx (random-fx/generate-random-number (fn [x] [::got-random-number x]))})

emccue 2021-04-25T17:46:53.338200Z

and then build functions on top of that to do more complicated things

emccue 2021-04-25T17:49:58.338400Z

(ns your.project.effects.random)

(rf/reg-fx 
  ::generate-random-number
  [when-done]
  (rf/dispatch-sync
    (when-done (Math/random))))

(defn generate-random-number [when-done]
  [[::generate-random-number when-done]])

(defn in-range [start-inclusive stop-exclusive when-done]
  (generate-random-number
    (fn [x]
      (let [choices   (range start-inclusive stop-exclusive)
            which-one (Math/floor (* x (- stop-exclusive start-inclusive)))]
        (when-done (nth choices which-one))))))

emccue 2021-04-25T17:50:23.338600Z

a non-trivial amount of re-inventing the wheel sure - feel free to make more randomness fx if its convenient to just call normal side effecting fns

emccue 2021-04-25T17:50:42.338800Z

but fundamentally you should be able to get by with very few reg-fx declarations

emccue 2021-04-25T17:51:07.339Z

(ns ...
  (:require [your.project.effects.random :as random-fx]))

(rf/reg-event-fx
  ::clicked-dice-roll-button
  [{:keys [db]} _ {:keys [roll-id]}]
  {:fx (random-fx/in-range 1 7 (fn [x] [::got-random-number roll-id x]))})

unwarysage 2021-04-25T18:26:48.339400Z

That's a very thorough explanation, and I'm gonna have to parse it at length. http://day8.github.io/re-frame/Interceptors/ I think gave the prompt I needed for my current issue, which was thinking that I need to get the even from the event-hander fn definition, into the the injected-cofx part of the declaration, when instead i should fetch the information I need out of the event in the context map.