Low expectations today because, it is a Sunday, and because I no longer have the thread of a specific documentation, or book to follow so I am taking shots in the dark, trying to make things work and learn something at the same time.
The expectation for today is to start building a small re-frame application. Something very simple. It would have made sense for me to build alongside reading the documentation but there's only so many hours in a day, it had to be split and this how I did it. For sure this is improving my understanding of re-frame.
I started by setting up my views. In my views I needed a wheel, to display a message, and also the result of the spin. For starters, the wheel is simply a button that says "spin".
(defn wheel []
(let [yn (re-frame/subscribe [::subs/yn])]
[:div
[:h3 "The wheel says " @yn]
[:input {:type "button" :value "Spin"
:on-click #(re-frame.core/dispatch [:spin])}]]))
The view is subscribing to the value of yn
in the database. I also added a random message, with wheel themed pun (I got a lot more puns coming!).
(def sayings ["Der wheel zur macht"
"Wheel power"
"Boys wheel be boys"
"Free wheel offering"
"Time wheel tell"
"Wheel Wheaton"])
(defn the-wheel-says []
(sayings (int (rand (count sayings)))))
Finally we can tie this up together in the main element:
(defn main-panel []
[:div
[:h1 "Hail the Wheel!"]
[:h2 [the-wheel-says]]
[wheel]])
After that I need to create the event, that happens on click:
(def yes-no-string ["YES" "NO"])
(re-frame/reg-event-db
:spin
(fn [db]
(let [spin-result (yes-no-string (int (rand 2)))]
(js/console.log "Spin result:" spin-result)
(assoc db :yn spin-result))))
However, the event handler should remain a pure function so for this I should be using a coeffect.
(re-frame/reg-cofx
:yn
(fn [cofx _]
(assoc-in cofx [:db :yn] (yes-no-strings (int (rand 2))))))
However, since I am not just merely updating the db
I need to switch the reg-event-db
to a reg-event-fx
. This StackOverflow answer has more details:
If your handler needs to access co-effects/produce effects then you'd use reg-event-fx and get the :coeffects value (and :db if necessary) from the handler's input. A common use case is when you need to access browser storage (e.g. cookies, local storage) but want to keep your handlers free of side-effects. So we end up with:
(re-frame/reg-event-fx
:spin
[(re-frame/inject-cofx :yn)]
(fn [cofx _]
{:db (assoc (:db cofx) :yn (:yn cofx))}))
(re-frame/reg-cofx
:yn
(fn [cofx _]
(assoc cofx :yn (yes-no-strings (int (rand 2))))))
Putting together this very simple re-frame loop was easy to get started with but understanding how to use the coeffects was a lot more complicated, which is ironic because it was not really needed in case, yet I wanted to be as as close to real world conditions as possible.
Tomorrow I will focus on styling the wheel, maybe make it spin as well!