re-frame

2024-08-21T20:27:12.537289Z

hey, i have an issue with re-frame and shadow-cljs hot reload. Full code and question in thread

2024-08-21T20:27:35.991489Z

Here is the code:

(ns 
  (:require [reagent.dom :as dom]
            [reagent.core :as r]
            [re-frame.core :as rf]
            [exfn.subscriptions]
            [exfn.events]
            ["moment" :as moment]))

;;==events =======================================

(rf/reg-event-db
 :initialize
 (fn [_ _]
   {:x 0
    :current-date (.startOf (moment) "month")}))

(rf/reg-event-db
 :next-month
 (fn [db _]
   (let [current-date (get-in db [:current-date])
         next-month (.add current-date 1 "month")]
     (-> db
         (update :x inc)
         (assoc :current-date next-month)))))

(rf/reg-event-db
 :prev-month
 (fn [db _]
   (let [current-date (get-in db [:current-date])
         prev-month (.subtract current-date 1 "month")]
     (-> db
         (update :x dec)
         (assoc :current-date prev-month)))))

;;==subscriptions ================================

(rf/reg-sub
 :current-date
 (fn [db _]
   (get-in db [:current-date])))

(rf/reg-sub
 :x
 (fn [db _]
   (-> db :x)))

;;==components ===================================

(defn calendar-header [] 
  (let [current-date @(rf/subscribe [:current-date])
        x @(rf/subscribe [:x])]
    [:div.calendar-header
     [:span
      [:i.fas.fa-chevron-left
       {:style {:padding-right "30px"
                :cursor "pointer"}
        :on-click #(rf/dispatch-sync [:prev-month])}]
        (str (.format current-date "MMMM YYYY"))
      [:i.fas.fa-chevron-right
       {:style {:padding-left "30px"
                :cursor "pointer"}
        :on-click #(rf/dispatch-sync [:next-month])}]]]))

(defn app 
  []
  [:div.container
   [calendar-header]
   [:hr]])

(defn ^:dev/after-load start []
  (dom/render [app]
              (.getElementById js/document "app"))) 

(defn ^:export init []
  (js/console.log "Initializing app")
  (start))

(defonce initialize (rf/dispatch-sync [:initialize]))

2024-08-21T20:28:37.153339Z

This displays the month at the top center of the page, like < August > and when I click the < or > it goes up and down the months. However, I'm having to add a simple property x and also increment / decrement it, otherwise nothing updates. However, if I click a chevron to go up / down, then hit ctrl+S to save my code, it seems to realise and update the page. e.g. it's on August, I click the right chevron twice and then trigger a reload, it will change August to October.

p-himik 2024-08-21T20:31:52.506749Z

moment.add mutates the object in-place. You don't get a new object, so Reagent doesn't detect any changes to it.

2024-08-21T20:32:09.358809Z

ah okay, that makes sense! I didnt realise it worked like that

p-himik 2024-08-21T20:32:13.349049Z

Right from its website: > As an example, consider that Moment objects are mutable. This is a common source of complaints about Moment.

2024-08-21T20:32:39.468059Z

Are there better alternatives to moment for working with dates ?

p-himik 2024-08-21T20:32:55.542599Z

Of course, and they're mentioned at https://momentjs.com/docs/.

2024-08-21T20:33:48.954149Z

thanks, I'll have a read!

👍 1
dehli 2024-08-21T21:08:58.512059Z

I've enjoyed using https://github.com/juxt/tick as a clj(s) specific library

👍 1