Re-Frame Javascript Interop
How can we embed native javascript objects into the Re-Frame data loop?
First lets create a Re-Frame app. You’ll need to install Clojure and Leiningen (a build tool) by following these instructions.
To create an application with just the base template, use this command:
$ lein new re-frame example-app
To run our app we can use the following command:
$ lein watch auto
Now we have our very own Re-Frame App running on http://localhost:8020 go and take a look!
To answer this lets first look at how we can interact with Javascript from Clojurescript:
- https://lwhorton.github.io/2018/10/20/clojurescript-interop-with-javascript.html#property-access
- https://cljs.github.io/api/cljs.core/js-obj
- https://www.spacjer.com/blog/2014/09/12/clojurescript-javascript-interop/
Let us start with creating a Javascript library that we can play with. Here is a basic library https://github.com/owodunni/exampleModule.
It exports some functions that will print to the log. That is handy in order to see that we are interacting with Javascript correctly.
Go ahead and install it to our Re-Frame App using:
$ npm install git+https://github.com/owodunni/exampleModule.git
We can try and use our example module from events.cljs
in the following way:
(ns example-app.events
(:require
[re-frame.core :as re-frame]
[example-app.db :as db]
[examplemodule :as ex]
))(re-frame/reg-event-db
::initialize-db
(fn [_ _]
(ex/logFunc "Hello from JS!")
db/default-db))
This will print a nice little greeting in our log!
How about adding a callback to a Javascript function? We can modify our code above:
(re-frame/reg-event-db
::initialize-db
(fn [_ _]
(ex/logAndCallbackFunc
"Hello from Javascript!"
(fn [] (prn "Hello from Clojurescript!")))
db/default-db))
This will give us two messages one printed in Javascript and one printed in Clojurescript.
Finally we can create a object and call its function. Hed over to db.cljs
there we have our default-db
lets add our logger to it:
(ns example-app.db
(:require
[examplemodule :as ex]))(def default-db
{:name "re-frame"
:logger (ex/Logger. "Almighty logger")})
We can now use our logger
wherever we have access to our db
lets use it in subs.cljs
:
(ns example-app.subs
(:require
[re-frame.core :as re-frame]))(re-frame/reg-sub
::name
(fn [db]
(.log (get db :logger) "calling from reg-sub")
(:name db)))
We will now have a new greeting waiting for us in the console!
Thats it! I hope that helped someone get a hang of Javascript Clojurescript interop.