on
JS literals (`#js`) improve runtime performance over `clj->js`
I was making a “rapid-scheduling app” that uses the Google Calendar API , which required I convert Clojure maps into JS objects.
This means the use of #js
or clj->js
I saw Paulus Esterhazy’s post which says I should do this:
(def config #js {:apiKey "..."}
:clientId "[...].apps.googleusercontent.com"
:discoveryDocs #js ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
:scope "https://www.googleapis.com/auth/calendar.readonly"))
(.log js/console (.-discoveryDocs config)) ;; => ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest']
This turned my vector to a GAPI-friendly array.
The #js reader macro (also called a js literal? ) converts only the top level into a js-obj or js-array. Nested things appear to be turned into objects. I first did this:
(def config #js {:apiKey "..."}
:clientId "[...].apps.googleusercontent.com"
:discoveryDocs ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
:scope "https://www.googleapis.com/auth/calendar.readonly"})
(.log js/console (.-discoveryDocs config)) ;; => {meta: null, cnt: 1, shift: 5, root: {…}, tail: Array(1), …}
This caused the GAPI to not load the Calendar object.
Albeit at the cost of run-time performance, clj->js
converted the nested vector to a JS array.
(def config (clj->js {:apiKey "..."}
:clientId "[...].apps.googleusercontent.com"
:discoveryDocs ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
:scope "https://www.googleapis.com/auth/calendar.readonly"))
(.log js/console (.-discoveryDocs config)) ;; => ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest']
GAPI used this array to load the calendar, and I can see my events, etc.
It’s a function run at runtime to turn clj maps to js objects instead of #js’s directly output JS array, so #js is preferred.