Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to list the properties and functions of a JavaScript object in ClojureScript?

Is there a simple way to list the properties and functions of a JavaScript object in ClojureScript?

I've tried the following:

(keys (js->clj (.getContext canvas "2d")))

But this throws the following error:

ExceptionInfo #<Error: [object CanvasRenderingContext2D] is not ISeqable>  clojure.core/ex-info (core.clj:4591)
like image 380
Odinodin Avatar asked Jun 30 '15 16:06

Odinodin


2 Answers

I figured out a way. You can just call

(js-keys (.getContext canvas "2d"))

and that will list all functions and properties of the JavaScript object.

like image 89
Odinodin Avatar answered Jun 23 '23 20:06

Odinodin


You are calling keys clojure function, which returns keys of a (clojure) map. To return all properties of javascript object you should do this :

(.keys js/Object myObject)

which is the analogy of javascript code :

Object.keys(myObject);

Edit : I just looked into the source of js->clj - https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs and I also tried it with canvas context. The problem is that the canvas context isn't a standard js/Object and therefore condition (identical? (type x) js/Object) is not satisfied and the js->clj function ends up in the else branch, which makes js->clj behave as identity function, which means that it just returns the context as you pass it in.

This is the source code :

(defprotocol IEncodeClojure
  (-js->clj [x options] "Transforms JavaScript values to Clojure"))

(defn js->clj
  "Recursively transforms JavaScript arrays into ClojureScript
   vectors, and JavaScript objects into ClojureScript maps.  With
   option ':keywordize-keys true' will convert object fields from
   strings to keywords."
 ([x] (js->clj x {:keywordize-keys false}))
 ([x & opts]
   (let [{:keys [keywordize-keys]} opts
      keyfn (if keywordize-keys keyword str)
      f (fn thisfn [x]
          (cond
            (satisfies? IEncodeClojure x)
            (-js->clj x (apply array-map opts))

            (seq? x)
            (doall (map thisfn x))

            (coll? x)
            (into (empty x) (map thisfn x))

            (array? x)
            (vec (map thisfn x))

            (identical? (type x) js/Object)
            (into {} (for [k (js-keys x)]
                       [(keyfn k) (thisfn (aget x k))]))

            :else x))]
       (f x))))
like image 41
Viktor K. Avatar answered Jun 23 '23 22:06

Viktor K.