0

One of the views in my Rails 4 app loads a simple javascript to create an instance of the Ace editor once the page loads...

$(function() {
  var editor = ace.edit("editor");
}):

In that view, I have a simple ajax button...

<%= button_to "Set Content", {controller: :pages, action: 'set_content'}, remote: true %>

that requests some unobtrusive javascript...

editor.setValue("New content has been set");

but this doesn't work. I'm guessing this doesnt work because editor isn't defined. Since ajax calls fail silently and I don't know how to debug unobtrusive javascript code using the same Chrome tools that I use debug normal javascript code, I can't verify that's the actual problem, but that's my best guess.

I was under the impression that if I write var editor, then is declared as a global variable that my unobtrusive javascript should be able to access.

My questions are...

  1. How can I access global variables inside of my unobtrusive javascript code?
  2. Since global variables are considered evil, is there a better way to access the editor variable from my unobtrusive javascript?

Thanks in advance for your wisdom!

2 Answers 2

3

when you use the var keyword inside a function, the scope of that variable is local to the function, so you are incorrect in your assumption about global scope. To make the variable global, declare it outside of your function:

var editor;
$(function(){
   editor = ace.edit('editor');
});

alternatively you could simply reference the window object (which is the 'global' object in browsers

$(function(){
   window.editor = ace.edit('editor');
});

With regards to avoiding global variables, it is reasonable to use a single global variable (often called 'app', or 'myCompany' or such to provide a namespace that is globally accessible.

var app = {};
$(function(){
  app.editor = ace.edit('editor');
});

This at least limits the scope of your new variables so you don't mistakenly overwrite global variables. However the real answer to avoiding global variables lies in the overall architecture of your app, which can't really be addressed without seeing more code. Generally speaking if ALL of the code you write is inside your jquery ready function, then you don't need global variables. Frameworks such as angular, ember, and backbone provide a much better structure for this type of thing than the ad-hoc code common with simple uses of jquery.

Sign up to request clarification or add additional context in comments.

Comments

2
$(function() {
  var editor = ace.edit("editor");
});

creates a local variable editor within the context of it's callback function. To access it elsewhere, you'll need to make it global window.editor = ace.edit("editor"), or add it to a namespace with something like

window.App = {};
App.editor = ace.edit("editor");

4 Comments

You beat me to it by 1 minute :P minor nitpick: Capitalized variable names are typically reserved for functions used with the New keyword, by convention.
@AllanNienhuis Namespaces are another common use of capitalization, along with Constructors and constants (which are often all caps).
I've seen the use of all caps for 'constants' - haven't noticed Capitalization for Namespaces, but I can see the point - to differentiate from 'regular' local vars. Cheers! :)
@AllanNienhuis It's not universal. Among popular libraries, Backbone, Ember and React capitalize their namespace, Knockout, Angular, jQuery, and d3 do not. But it's certainly a very common convention and not wrong.

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.