I'm developing RIA with clojure and clojurescript. Backend uses hiccup to generate a resulting html, like
(html5
[:head
(include-js "/js/my-cljs-generated.js")]
[:body ... ])
How can I pass edn(hashmap, vector, etc.) to clojurescript within the resulting html, i.e. without doing ajax call?
I would like to make hiccup do something like this:
(include-edn
"var_name" {:foo :bar}) ; or any other clojure data
and to be able to access the passed edn from cljs somehow(e.g. by name).
Currently my implementation is a bit hacky and stores edn in a global js var
(hiccup/javascript-tag (str "var edn = \""
(pr-str my-clojure-data) "\";"))
and on cljs side does smth like
(jayq/document-ready
(fn []
(if-let [edn (.-edn js/window)]
(do-something-with (cljs.reader/read-string edn))
)
...
)
Maybe there is more idiomatic way of achieving this?
Your approach is fine. If you're concerned about the manual creation of JavaScript code, an alternative would be to put the result of pr-str
as data in a well-defined element. Something along the lines of:
[:div {:style {:display "hidden"}
:id "server-originated-data"
:data-var-1 (pr-str var-1)
:data-var-2 (pr-str var-2)}]
You can then get that data from ClojureScript with something like:
(defn get-data
[tag]
(-> (.getElementById js/document "server-originated-data")
(.getAttribute (str "data-" tag))
(cljs.reader/read-string)))
Though, again, your approach is fine.
Your "implementation" is perfectly fine. Wrap it in a function if that makes you feel more comfortable :)
It wouldn't make a difference if you emitted e.g. compiled ClojureScript instead; the value would be still global and mutable.
You could consider a push (event-based) approach, rather than pull: place your generated edn data as a string inside a [:script] tag as an argument to a javascript call a clojurescript function. When the script is loaded by the browser it will send the edn to your handler function, allowing it to be loaded by your application.
This would be a little more idiomatic than your current approach as it doesn't require state or global data, and could easily be adapted to use ajax later, if required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With