23

I have views in my application that reference my application.js file which contains functions I use throughout my application.

I just installed the Rails 3.1 release candidate after having used the edge version of 3.1. Until I installed the RC I wasn't having any problems but now I'm getting this error:

ReferenceError: Can't find variable: indicator_tag

indicator_tag is a function I defined in application.js. The only difference I notice in the javascript file is that now all my functions are wrapped in:

(function() { ... }).call(this);

I understand this is for variable scoping? But could it be preventing my pages from using those variables? And before anyone asks, I've made sure the javascript paths are correct in my include tags.

5
  • Are you trying to reference indicator_tag from a file other than application.js.coffee? Commented May 22, 2011 at 18:50
  • No, it is in application.js.coffee. Commented May 22, 2011 at 18:55
  • Could you paste the contents of your script? Commented May 22, 2011 at 19:03
  • You're trying to call indicator_tag from inline scripts in your view? Commented May 22, 2011 at 19:14
  • Not inline, but a separate javascript file just for that page. The include tag for that file is below the one for application.js. Here are the contents of that file pastie.org/1957528 Commented May 22, 2011 at 19:19

2 Answers 2

47

By default, every CoffeeScript file is compiled down into a closure. You cannot interact with functions from a different file, unless you export them to a global variable. I'd recommend doing something like this:

On top of every coffeescript file, add a line like

window.Application ||= {}

This will ensure that there's a global named Application present at all times.

Now, for every function that you'll have the need to call from another file, define them as

Application.indicator_tag = (el) ->
  ...

and call them using

Application.indicator_tag(params)
Sign up to request clarification or add additional context in comments.

2 Comments

Dogbert's answer is correct. (Note that you could also use this/@ to export variables as globals in this case, e.g. @indicator_id = ..., since CoffeeScript's wrapper is called in the global context). The reason you're just bumping into that now is that earlier versions of Rails 3.1 disabled CoffeeScript's wrapper. This behavior was classified as a bug and fixed for RC1: github.com/rails/rails/issues/1125
I would give you 10 ^s if I could for that answer. Thanks so much.
13

Dogbert's solution is a great way to go if you have a very sophisticated JS back-end. However, there's a much simpler solution if you only have a handful of functions you're working with. Just add them directly to the window object, like this:

window.indicator_tag = (el) ->
  ...

Then you can use your functions from anywhere without having to wrap them up in another object.

2 Comments

What's so bad about wrapping them in another object? If you want to avoid typing "Application" call it "App". The context is often really useful anyway when you're just reading the code…
And, I would add than this "window." is the same than "@", isn't it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.