beginners

Vincent 2025-04-15T16:46:46.936309Z

I am using FullCalendar for a project and want to catch the clicks to the actual calendar and make appointments that way via popup modal. But the atom is not ready when I click on the widget and I get cannot read props.

Vincent 2025-04-15T16:47:39.331129Z

I'm running into some issues because i have an app-state atom that is defined at the top of my core.cljs file, and it is not initialized when someone clicks the calendar widget. I keep getting cannot read properties of undefined (reading 'app-state')

Vincent 2025-04-15T16:48:07.512249Z

I'm wondering if there's a way to delay things so that it will work? I tried delaying to "onload" but that doesn't work neither

Vincent 2025-04-15T16:53:30.225309Z

I think ^:export is part of the solution but I'm not sure what else

p-himik 2025-04-15T17:06:31.993179Z

We need more details to provide any kind of help. What's FullCalendar? What's the source code? What's app-state? And so on.

Vincent 2025-04-15T17:32:00.000829Z

Let's see...

Vincent 2025-04-15T17:32:07.235749Z

<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.js'></script> is the fullcalendar drop-in

Vincent 2025-04-15T17:32:26.178739Z

Grok gave

Vincent 2025-04-15T17:32:51.592469Z

<script>
    var globalCalendar;
    document.addEventListener('DOMContentLoaded', function() {
      var calendarEl = document.getElementById('calendar');
      if (calendarEl) {
        globalCalendar = new FullCalendar.Calendar(calendarEl, {
          initialView: 'timeGridWeek',
          dateClick: function(info) {
            console.log('Date clicked:', info.dateStr, 'Date object:', info.date);
            if (window.tomyappt005 && window.tomyappt005.handleDateClick) {
              window.tomyappt005.handleDateClick(info.dateStr);
            } else {
              console.error('tomyappt005.handleDateClick not found');
            }
          },
          slotMinTime: "08:00:00",
          slotMaxTime: "18:00:00",
          allDaySlot: false
        });
        globalCalendar.render();
      } else {
        console.error('Calendar element not found');
      }
    });
  </script>
as a way to pass the date to handleDateClick in the clojurescript app

Vincent 2025-04-15T17:33:53.051459Z

Then I have a clojurescript part that goes something like

(set! (.-tomyappt005 js/window) #js {})
(set! (.-handleDateClick (.-tomyappt005 js/window))
      (fn [date-str]
        (js/console.log "ClojureScript received click for date:" date-str)
        (swap! appstate assoc
               :show-modal true
               :modal-date date-str)))

Vincent 2025-04-15T17:34:29.416229Z

in theory that should capture the date-str and swap the appstate atom which looks like

(defonce appstate
  (r/atom {:polled-data {}
           :current-user {:id 1
                          :role "admin"}
           :forms {:appointment {}
                   :user {}
                   :client {}
                   :insurance {}
                   :service {}}
           :last-refresh nil
           :show-modal false ;; Add for modal visibility
           :modal-date nil   ;; Store clicked date
           :search {:type :interpreter
                    :selected-id nil
                    :start-date nil
                    :end-date nil
                    :results []
                    :selected-appointments #{}}}))

Vincent 2025-04-15T17:34:54.926139Z

... when I click on the page I do get the handleDateClick to print out that it got the date, but then the swap fails

p-himik 2025-04-15T17:36:42.251579Z

Wow, OK. So, to get it out of the way - IMO if you're a beginner, you really, really should not be using an LLM to generate some awful garbage for you. All that stuff with DOMContentLoaded, js/window, ^:export is literally the worst way to do it, and cannot work in principle if the element with id="calendar" is created by Reagent.

Vincent 2025-04-15T17:38:16.456959Z

the calendar is hard-coded into the page basically, it's the appstate that's a reagent atom

p-himik 2025-04-15T17:39:26.063499Z

What I would do instead: 1. Install fullcalendar as a proper NPM dependency as opposed to using it via a CDN 2. Import Calendar 3. Create a Reagent component that wraps Calendar and passes it a DOM node via a ref and any handlers as plain function objects That's is, easy-peasy. The only possible hiccup is the first item, but the chance of something going wrong is about 1%.

Vincent 2025-04-15T17:40:19.761449Z

oh, don't use it via CDN? that makes sense. there's probably some good documentation about npm deps via cljs?

p-himik 2025-04-15T17:40:50.329819Z

If you use shadow-cljs, the docs are perfect, yes. No clue about vanilla of figwheel-main - I haven't used those in many years.

Vincent 2025-04-15T17:42:17.852339Z

yeah it's shadow-cljs here

Vincent 2025-04-15T17:43:00.169659Z

is there a logical reason something like this won't work though?

(def handleDateClickVal (atom nil))
(set! (.-tomyappt005 js/window) #js {})
(set! (.-handleDateClick (.-tomyappt005 js/window))
      (fn [date-str]
        (js/console.log "ClojureScript received click for date:" date-str)
        (swap! handleDateClickVal assoc
               :show-modal true
               :modal-date date-str)))
that is, make a new atom, and then swap! the atom with the handleDateClick that gets invoked from the widget?

Vincent 2025-04-15T17:43:58.840439Z

I'm a little confused by what you mean by "Import Calendar" you mean in the requires/imports?

p-himik 2025-04-15T17:45:47.191449Z

> is there a logical reason something like this won't work though? It can fail in an optimized build if any of the fields that you set are minified in CLJS code but aren't minified in the JS code extrinsic to the CLJS code. But maybe fields that get set! on js/something directly or transitively aren't minified - I don't know. > you mean in the requires/imports? Yes, just like the README of FullCalendar suggests in its repo. Of course, it talks about JS imports but you can translate those to CLJS with the help of shadow-cljs docs.

Vincent 2025-04-15T17:49:59.402019Z

Okay cool. I will ask in shadow-cljs about the npm dependency. Ty

Vincent 2025-04-15T17:54:19.221539Z

Nice! I was able to import the Calendar so now I can use native methods on it? What did you mean by reagent component that wraps the cal?

Vincent 2025-04-15T17:56:24.044279Z

err spoke too soon, don't have it working quite yet ...

Vincent 2025-04-15T17:58:23.645359Z

okay i needed some extra plugins. it's rendering now ^_^

Vincent 2025-04-15T18:04:46.490479Z

hey I got it working! 😄

Vincent 2025-04-15T18:04:54.124799Z

thanks @p-himik you're a life saver

👍 1