Why can't I call seq functions in a sequence generated by js->clj?

clojure, clojurescript

Solution

The `js->clj` only changes something that is exactly a JavaScript object (it is implemented using `instance?` instead of `isa?`, and with good reasons), when you pass a descendant of `js\Object` `js->clj` returns the same object. `aget` (and `aset`) works because it compiles down to the `object[field-name]` syntax on JavaScript.

You can extend the `ISeq` protocol (or any other protocol) to the `goog.events.BrowserEvent` and all functions that works with `ISeq` will work with `goog.events.BrowserEvent`. There is a talk by Chris Houser where he showed how to extend a bunch of protocols to a goog Map. I recommend watching the whole talk, but the part that are relevant to your question begins at approximately 14 minutes.

Problem

Although I can get turn a simple js object into a clojure object with something like; ``` (-> "{a: 2, b: 3}" js* js->clj) ``` I'm apparently not being able to do so with a particular object, `goog.events.BrowserEvent`, in a handler function like: ``` (defn handle-click [e] ... (-> e .-evt js->clj keys) ;; <------------- ... ``` The function does get applied, but the resulting object doesn't respond to sequence functions like `count`or `first`, although I can fetch items using `aget`. The error message I get, in chrome's console, is; ``` Uncaught Error: No protocol method ISeqable.-seq defined for type object: [object Object] ``` Why is this happening? Shouldn't `js->clj` work with all objects? How can I fix this? Thanks!

Original source