Hi, This is a common error, you're not alone.
The problem is that the function you're creating in the loop (the anonymous function assigned to `onComplete`) has an *enduring reference* to the `qnum` variable, not a *copy* of its value when the function was created. All copies of your `onComplete` callback use the same variable, which by the time they use it will have the value as of the *end* of the loop. This is how closures (functions that "close over") data work, they have an enduring reference to the variables. Closures are not complicated[1], there are just a couple of basics that people tend to misunderstand if they haven't had them explained to them. First I'll tell you how it's usually solved, then how you can solve it with useful features Prototype providers, and then recommend a completely different approach: The usual way to solve it is to create a factory function that creates functions for you that close over a variable they each have a private copy of, assigning the value of `qnum` at a point in time to those variables as we create them, like this: function fillQuiz() { var qnum = 0; var tget = 'q' + qnum; while ($(tget)) { new Ajax.Updater($(tget), 'qblock.php', { method: 'get', parameters: {qnum: $(tget).readAttribute('qnum')}, // Here we *call* a function that returns a function onComplete: createCallback(qnum) }); qnum++; tget = 'q' + qnum; } function createCallback(q) { // This closure closes over `q`, which is private // to the closure and never changes. return function() { qListen(q); }; } } function qListen(_me) { window.alert(_me); } There, we use `createCallback` to create and return a function for us that closes over the `q` argument, which is created for each call. That way, the returned function closes over something that doesn't change. The good news is you don't have to write `createCallback`, because Prototype already has one: `Function#curry`[2]. `Function#curry` does exactly what we want, it accepts arguments and returns a function that will call the original function with those arguments. So with Prototype, that code gets a bit simpler: function fillQuiz() { var qnum = 0; var tget = 'q' + qnum; while ($(tget)) { new Ajax.Updater($(tget), 'qblock.php', { method: 'get', parameters: {qnum: $(tget).readAttribute('qnum')}, onComplete: qListen.curry(qnum) }); qnum++; tget = 'q' + qnum; } } function qListen(_me) { window.alert(_me); } So that's the general solution, and how Prototype helps with it. What's the completely different approach? Ajax calls are expensive, and you can only have so many of them going at a time. Rather than firing off separate ajax requests for *every question*, I'd strongly recommend firing off one request with a list of questions, and having the request reply with all of the results in one go. That eliminates the loop, solving the problem related to the loop, and reduces server load. [1] http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html [2] http://api.prototypejs.org/language/Function/prototype/curry/ HTH, -- T.J. Crowder Independent Software Engineer tj / crowder software / com www / crowder software / com On Jul 15, 5:26 pm, "Heath Jordan" <hjor...@cascadeauto.com> wrote: > I am using an anonymous function so I c an pass args. I need the arguments > to be variable and when they actually get called they are the final state of > the variable not the state at which I 'think' I am setting them. > > function fillQuiz() > > { > > var qnum = 0; > > var tget = 'q' + qnum; > > while($(tget)!= null) > > { > > new Ajax.Updater($(tget), 'qblock.php', { > > method: 'get', > > parameters: {qnum: $(tget).readAttribute('qnum')}, > > onComplete:function(){qListen(qnum)} > > }); > > qnum++; > > tget = 'q' + qnum; > > } > } > > function qListen(_me) > > { > > window.alert(_me); > > > > > > > > } -- You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptaculous@googlegroups.com. To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.