Hi Gilbert,

Building on what Colin said, I'd suggest reading up a bit on
JavaScript and "this", it's not quite the same as some other languages
you might be familiar with.  If you don't already have a good
JavaScript book, I'd recommend "JavaScript: The Definitive Guide" by
David Flanagan[1][2].  I've done a couple of blog entries[3][4] that
may help as well.

You have a couple of options for solving the problem.  One is to use
Function#bind[5] as Colin said.  You can do that with a named
function, or even with your current anonymous function by wrapping the
whole thing in () and putting .bind(this) at the end of it:

* * * *
var url = "path-to-php-script-&sid="+Math.random();
var req = new Ajax.Request(url, {
    method: 'get',
    contentType: 'application/xml',
    onComplete: (function(transport) {
        var res = transport.responseXML;
        var cap_nodes = res.getElementsByTagName('group');
        for(i=0; i < cap_nodes.length; i++){
            this.cap_questions.push(cap_nodes[i].childNodes
[0].nodeValue);
        }).bind(this)
    }
});
* * * *

...but that's pretty awkward to read.  (The parens may or may not be
necessary; I'd include them for clarity if nothing else.)
Alternately, you can make the handler a function you define elsewhere
and just use in the request:

* * * *
// Somewhere in your class definition
handler: function(transport) {
     var res = transport.responseXML;
     var cap_nodes = res.getElementsByTagName('group');
     for(i=0; i < cap_nodes.length; i++){
         this.cap_questions.push(cap_nodes[i].childNodes
[0].nodeValue);
     }
},

// Where you want to use it
var url = "path-to-php-script-&sid="+Math.random();
var req = new Ajax.Request(url, {
    method: 'get',
    contentType: 'application/xml',
    onComplete: this.handler.bind(this)
    }
});
* * * *

But if you really want to define it inline, you can just make use of
the fact that it's already a closure and you don't need Function#bind
at all -- just declare a variable and set its value to 'this', and
then use that variable within the closure:

* * * *
var self = this; // For use within the closure below
var url = "path-to-php-script-&sid="+Math.random();
var req = new Ajax.Request(url, {
    method: 'get',
    contentType: 'application/xml',
    onComplete: function(transport) {
        var res = transport.responseXML;
        var cap_nodes = res.getElementsByTagName('group');
        for(i=0; i < cap_nodes.length; i++){
            self.cap_questions.push(cap_nodes[i].childNodes
[0].nodeValue);
        }
    }
});
* * * *

If you're not sure what I mean by "closure" and how that works,
Flanagan[1][2] covers it a bit and I've written a bit about it[6][7].

(BTW:  In my examples above, I've declared 'res' and 'cap_nodes' as
vars within the function.  Your example didn't do that, and so they
become globals[8], which will almost certainly give you trouble at
some point.)

[1] http://www.oreilly.com/catalog/jscript5/
[2] http://www.amazon.com/dp/0596101996
[3] http://blog.niftysnippets.org/2008/03/mythical-methods.html
[4] http://blog.niftysnippets.org/2008/04/you-must-remember-this.html
[5] http://prototypejs.org/api/function/bind
[6] http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html
[7] http://blog.niftysnippets.org/2008/03/closures-by-example.html
[8] http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals.html

HTH,
--
T.J. Crowder
tj / crowder software / com
Independent Software Engineer, consulting services available

On Apr 27, 5:28 pm, IMBI-Indie-Portal <imbil...@tpg.com.au> wrote:
> Thanks T.J.
>
> I probably should have been more specific.
>
> I'm actually building a Q and A Captcha, not a Logger. I used that as
> an example.
>
> The issue is, I am using proto's Ajax.Request and I'm running that
> code within the 'onComplete: function(transport){ callback }' and this
> is executing within a method which get an array of questions from a
> database.
> Another method then creates a select list and renders it to the page.
>
> I have found that if I declare a var using the 'this.arrayName' before
> running the Ajax.Request I can load the array OK.
>
> What is strange, is that I can then do 'this.ArrayName  = var;' and
> populate the objects array whilst I'm still in the  'onComplete
> callback'.
>
> Why is it that I cant load the this,arrayName as shown, but it lets be
> 're-value it'??
>
> Here is a sample of the code: some var declarations are Not show for
> simplicity...
>
> var qArr = this.cap_questions; // I CREATE THE USABLE VAR WORKAROUND
> HERE ????
> var url = "path-to-php-script-&sid="+Math.random();
> var req = new Ajax.Request( url, {      // I USE THE var = req TO MAKE
> JSLINT HAPPY ??
>         method: 'get', contentType: 'application/xml', onComplete: function
> (transport) {
>                 res = transport.responseXML; cap_nodes = 
> res.getElementsByTagName
> ('group');
>                 for(i=0; i < cap_nodes.length; i++){
>                         qArr.push(cap_nodes[i].childNodes[0].nodeValue);
>                 }
>                 this.cap_questions = qArr; // HERE IT LETS ME RE-DECLARE THIS
> OBJECTS VALUE?????
>         }
>
> });
>
> If I try to declare the VAR within the callback it won't work either,
> Has to be before the new Ajax.Request.
> I checked with 'typeof' and it returns 'undefined'....
>
> I have another problem as well.
>
> How can I call a method within another method, like in PHP.
>
> Using 'this.methodName()" does not seem to work.
> After completion of one methods db retrieval, I do a check for state,
> and would like to call a method within the working method.
> The idea worked (as functions) before I re-wrote the whole idea into
> a  single class.
> I want the class to be as dynamic as possible, and dont want to have
> to add more intelect to the pages code.
> This will be a publicly available App, so I'm trying to make it as
> simple as possible to setup.
>
> Thanks again for the Quick HELP. Its much appreciated!
> Cheers, Gilbert R..
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to