Fork me on GitHub

Do I have to learn Reactjs to work with reagent clojusrscript ?

Léo J06:11:50

so far I didn’t need too but I’m fairly new

Léo J06:11:03

I’m using re-frame (which uses reagent)


does re-frame require reactjs ?

Léo J06:11:10

as a dependency yes, as far as I understand, re-frame uses reagent to DOM rendering which uses react for that 😄

Léo J06:11:09

I’ve a public example here (albeit, it’s not necessarily a good one since it was my first clojurescript attempt)

Léo J06:11:03

you’re welcome 🙂


Is not necessary, but it makes thinks easier. You should at least read and the official docs

Romit Gandhi06:11:09

I want to use this package in re-frame shadow-cljs. I have installed this package using npm. Imported in require

["react-toastify" :refer [ToastContainer toast]]
In one place I have put
[:> ToastContainer]
but tried to call toast function on button click but didn't work properly. Can anyone tell me how to call it and display toast notification. Thank you.


Are you sure you have added the CSS to your index.html? You should also post snippets of your code if possible :)

Romit Gandhi17:11:43

It was CSS issue, when I added CSS it worked. Thanks for the help. The only issue is I have to get CSS from and paste it in CSS file manually as I didn't find any way to import it. Do you know any other way to import CSS? Thank you.

👍 1

The way I handled this for react-toastify was to import the package’s css directly from unpkg in my html file. You could also rewrite react-toastify’s css using something like Stylefy and add it to your dom, but I don’t think doing this is worth the trouble.


As far as I know (from reading shadows’ documentation) it is impossible to import css files directly inside your cljs files.

Romit Gandhi04:11:58

Okay, Thanks for the help 🙂


I’m using to read Excel spreadsheets in my Clojurescript project. I can call the top-level functions in the XLSX namespace fine, (e.g (.read js/XLSX raw-data (clj->js {:type "binary"})) succeeds in but I’m struggling to use functions in the XLSX.utils namespace, e.g. XLSX.utils.sheet_to_json()


No reason to use clj->js when its data you are writing out


#js {:type "binary"} will do what you want


I can get a reference to the function via (def stj (goog.object/get (.-utils js/XLSX) "sheet_to_json")) and (goog.functions/isFunction stj)) returns true but when I call it, I just get an empty array. What am I doing wrong?


I have a (require ["xlsx" :as xlsx]) and with that I do stuff like

(p/then (fn [downloaded]
                  (let [wb (xlsx/utils.book_new)]
                    (doseq [[k data] downloaded]
                      (xlsx/utils.book_append_sheet wb (xlsx/utils.aoa_to_sheet data) (name k)))
                    (xlsx/write wb #js {:type "buffer"})))))))


Core bit here (xlsx/utils.aoa_to_sheet data)


just sharing a more complex example for additional context


hope this helps


This is with cljsjs/xlsx right? Thanks for the pointer. I’ve added a call to sheet_to_json in the form you suggest and have code running in a test like

(require ["xlsx" :as xlsx]

(async done
         (let [raw-data (<! test-util/file-reads)
               raw-wb (xlsx/read raw-data (clj->js {:type "binary"}))
               raw-sheet-by-index  (.-Sheets raw-wb 0)
               raw-sheet-by-name (.-Sheets raw-wb "first-sheet")
               sheet (xlsx/utils.sheet_to_json raw-sheet-by-name)
               (prn "raw-wb is " raw-wb)
               (prn "raw-sheet-by-name" raw-sheet-by-name)
               (prn "sheet" sheet)
               (is (= raw-sheet-by-name raw-sheet-by-index))
All compiles and runs, but the (prn "sheet" sheet) gives #js []


I’ve checked out the JavaScript function on and it works fine there.


I’m just about ready to roll my own sheet processing code :-)


No, I’m using it from npm


Hmm, could be the crucial difference, possibly. I’m targeting the browser


I an indeed targeting node but I think in theory this shouldn’t make much of a difference


Perhaps the problem is with this being bound to a wrong object. a.b() is not the same as x = a.b; x().


Thanks…but looks like its a pure fn. Anyway I tried adding these two lines to the let clause:

stj-fn xlsx/utils.sheet_to_json
 sheet-2 (stj-fn raw-sheet-by-index)
and same (empty) result.


I see. Well, it should be easy to debug it then using your browser's debug capabilities. Just put a breakpoint there and step through the function and see what's going on.


I’ve figured out what’s going on, though I don’t understand quite why. The clojurescript:

(let [raw-sheet-by-name (.-Sheets raw-wb "first-sheet")]
  (prn "raw-sheet-by-name))
gives this result:
"raw-sheet-by-name" #js {:first-sheet #js {:!ref "A1:C9", :A1 #js {:t "s", :v "Name", ...}, ...
(i.e. the actual sheet values are wrapped in an outer object); but the JavaScript:
var worksheet = workbook.Sheets['first-sheet'];
gives the sheet values directly:
{!ref: "A1:C9", A1: {h: "Name",...}...}
but (aget (.-Sheets raw-wb) 0) gives the unwrapped object. I thought that was equivalent to (.-Sheets raw-wb 0) :thinking_face:


Thanks for your help on this


AFAIK (.-Sheets raw-wb 0) is not even a valid CLJS - perhaps it's working because you have an outdated version of CLJS. Using aget is definitely the correct way, if the value of .-Sheets is an array. If it's an object, use proper JS interop for that - either via more .- or with goog.object/get. Plenty of materials on the question of CLJS-JS interop, but feel free to ask more questions if something doesn't work.


Good point! I’ve been barking up the wrong tree. That second argument 0 is just ignored. (.-Sheets raw-wb) is an object, and because the property names are sheet names of an Excel spreadsheet, they are strings, possibly with embedded spaces, so I need to use goog.object/get .


(I’m using the latest CLJS 1.10.891 btw)


Yeah, seems like on 1.10.893 that last argument is not ignored:

ClojureScript 1.10.893
cljs.user=> (.-a #js {} 0)
Unexpected error (Error) compiling at (<cljs repl>:1:1).
Unknown dot form of (. #object[cljs.tagged_literals.JSValue 0x2ecb87b2 "cljs.tagged_literals.JSValue@2ecb87b2"] -a (0)) with classification [:cljs.analyzer/expr :cljs.analyzer/property :cljs.analyzer/expr]


Ah that would have been useful. Strange though, I can reproduce that in a repl, but the same line in my test code compiles fine…