clojurescript why: (def ... is failing whereas (let ... succeeds

123 views
Skip to first unread message

billh2233

unread,
Feb 10, 2012, 6:44:39 PM2/10/12
to Clojure
I don't understand (def someVar (newInstantiatedGoogFxObject...)).
Why does (def someVar (new-goog-fx-object ...)) fail whereas (let
[somevar (new-goog-fx-object ...) ] works?

I'm trying to define a variable using def and instantiate a new
goog.fx.DragDrop, but this clojurescript:

(def dragSource (fx/DragDrop. "myText" "stuff"))

produces this javascript and resulting error:

dom.test.dragSource = (new goog.fx.DragDrop("myText","stuff"));

-->Uncaught TypeError: undefined is not a function

whereas the let-based version instantiates and executes just fine:

(defn run-draganddrop []
(let [dragSource (fx/DragDrop. "myText" "stuff")]
...
)
)

-----------------------
Here is the actual source file:

(ns dom.test
(:require [goog.fx :as fx]
[goog.graphics :as graphics]
))

;FAILS in the browser. It requires the expression to be a function.
The expression is undefined.
;IMO the expression should produce a new object and should not be a
function.
(def dragSource (fx/DragDrop. "myText" "stuff"))

;SUCCEEDS.
(defn run-draganddrop []
(let [dragSource (fx/DragDrop. "myText" "stuff")]
)
)

Thanks. Bill

Gijs S.

unread,
Feb 11, 2012, 10:09:27 AM2/11/12
to Clojure
Hi,

The solution is to explicitly require goog.fx.DragDrop in the :require
in the ns declaration:

[goog.fx.DragDrop :as dd-import]

This adds this line in the generated js output:
goog.require('goog.fx.DragDrop');

This line is required because DragDrop lives in its own file within
the Google Closure Library.

Also, your second example with the let form doesn't succeed. Try
calling the "run-draganddrop" function and it will gave the same error
as the failing def case. Using the "let" here makes that the
expression is never reached and executed because the function is never
called, which is why the error does not show. This case is also solved
by adding the DragDrop to require.

-Gijs

Kevin Lynagh

unread,
Feb 10, 2012, 8:13:26 PM2/10/12
to Clojure
How do you know the let is working?
Is the run-draganddrop function being called by something outside of
that source file?
It'll have the same problem as the def, you just won't see it when you
load the file because the function isn't called.

I looked into goog.jar and goog.fx.DragDrop is an entire namespace, so
you need to explicitly require it so ClojureScript will bring it into
the compiled JS:

(:require [goog.fx.DragDrop :as _]
[goog.fx :as fx]
[goog.graphics :as graphics])


If you look inside the Closure library jar (goog.jar) at goog/fx/fx.js
only requires the following:

goog.require('goog.asserts');
goog.require('goog.fx.Animation');
goog.require('goog.fx.Animation.EventType');
goog.require('goog.fx.Animation.State');
goog.require('goog.fx.AnimationEvent');
goog.require('goog.fx.easing');


which is why DragDrop isn't picked up.

best,

Kevin
Reply all
Reply to author
Forward
0 new messages