I hope the title is self-explanatory …

Several times, in a symfony project or a project which runs with the help of the prototype library, some problems arise regarding the scope of certain javascripts variables declared inside ajax request (that can be theyselves declared within other ajax request).

Usually , you need to access certain javascript varible or function that is declared on a place which can be outside the scope of the ajax request you’re calling that variable / function from.

This example: (written in symfony) will not work, because it’s written on an ajax request response already

echo javascript_tag("
 var pageOkCodigoAcceso='".url_for('corbatas/compra')."';
".remote_function(array(
 'update'=>'div_formulario_codigo_acceso',
 'url'   => 'forms/codigoAcceso',
 'script'=> 'true',
 'with' => "'complete_callback=garbageDisposal'",
 'complete' => "garbageDisposal()",
 'method'=>'get'))."
function garbageDisposal()
 {
 $('codigoAcceso_submitButton').value='activar oferta';
 }
 ");

in this case, pageOkCodigoAcceso is a javascript variable which the ajax-generated content at div_formulario_codigo_acceso will need to access.
garbageDisposal() is a simple javascript function that will be executed upon completeness of the ajax request described inside the remote_function tag.


But, since all this code is part of an ajax request (yes, we’re making an ajax request from inside another ajax request), the javascript code we put in there does not work
exactly the same way as if we put it on a regular .js file. When you put javascript code inside an ajax response, it won’t be evaluated unless you specify the contrary, and even
in that case, the scope is somehow ‘limited’
. So for the first thing :

  • we need to make sure that -if we’re going to put some nice javascript inside our ajax request-, that code is evaluated. this is achieved (in prototype & symfony) thanks to the option (“script” => “true”) that you can see in the code shown above.

And that’s not enough, my friend. because of the eval() process, the scope of these variables is not as wide as we’re used to. In the code above, the response javascript code
may have not access to the pageOkCodigoAcceso variable, neither to the function stated in the “complete” option: garbageDisposal(). This is because we currently are inside an
ajax response and, although the javscript is evaluated, each evaluation is isolated from it’s surroundings, and , of course, the ajax response that we get from within
the ajax response
we’re calling it from, can’t access them. however, there is a solution:

  • in order to make sure we have “full scope” for a variable or function, we declare it as a “window” property. This way, our code looks like this:
echo javascript_tag("
window.pageOkCodigoAcceso='".url_for('corbatas/compra')."';

".remote_function(array(
'update'=>'div_formulario_codigo_acceso',
'url'   => 'forms/codigoAcceso',
'script'=> 'true',
'with' => "'complete_callback=garbageDisposal'",
'complete' => "garbageDisposal();",
'method'=>'get'))."
window.garbageDisposal =
function()
 {
$('codigoAcceso_submitButton').value='activar oferta';
}

and everything will work just fiiiiiine.

Disclaimer: I’m perfectly aware I have probably said one thousand wrong things. It’s just it’s hard for me to explain this in “plain english” (I would be as hard in “complex english”, since I’m spanish). PLEASE FEEL FREE TO CORRECT ME.


3 Comments on “Scope of javascript variables within ajax requests”

You can track this conversation through its atom feed.

  1. Carlos Escribano says:

    In short: every variable or function you want to preserve in the global page context trough an AJAX response must be attached to the global window object (that is present everytime). But it’s a good explanation.

  2. Angel says:

    Very Good Post, thanx a lot

  3. uhui says:

    thanks alot bro.. this is very useful code for me

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>