[Proto-Scripty] Re: Using this.arrayname to add data to an array not working

2009-04-30 Thread IMBI-Indie-Portal

Hi, Yes I found some good info by Mr Crockford and friends a few weeks
ago.
I was looking up some info on advanced AJAX security techniques.

Found these pages:
http://www.webdirections.org/resources/douglas-crockford-ajax-security/
Some interesting presentation slides...
and from there a link to:
http://www.codinghorror.com/blog/archives/001175.html

Unfortunatly I wont be buying any more books untill I get a job.
Have an Interview with a 'recruiting crowd' today [friday].
Fingers crossed..

I have now replaced the XML in the Q and A app with JSON, and, added
caching for the fetched q and a sets.
Works like a dream.

Any thoughts yet on why the bind() function won't work within the
Ajax.Request??

Not important, just curious..
Mabye its an unexpected bug in the prototype AJAX implementation?
Is there another group/list where that question might be more
appropriate?

Thanks Again!
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Using this.arrayname to add data to an array not working

2009-04-28 Thread ColinFine

Your problem is that you are making (reasonable but wrong) assumptions
about what 'this' is bound to.

Inside a function (which is the only level of scope that Javascript
has), 'this' is not set, and therefore refers to the global object
(the window) unless you have done something explicit to cause it to be
bound to something else.

The usual case is that you call the function using the 'method'
invocation, in which case 'this' is bound to the object on which the
method was called.

I'm not certain what 'this' will be bound to in your example, ('new'
confuses me) but I think it is the new Ajax.Request object you are
creating, Whatever, it will *not* be whatever 'this' is bound to
outside the call.

Prototype has a method Function#bind for setting 'this' explicitly in
a function.


Colin Fine
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Using this.arrayname to add data to an array not working

2009-04-28 Thread T.J. Crowder

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);
                 

[Proto-Scripty] Re: Using this.arrayname to add data to an array not working

2009-04-28 Thread IMBI-Indie-Portal

Hi! Thanks T.J and Colin.

So Far So Good!

I stayed with the 'inline method', to save code.

I could Not get the bind() to work within the Ajax.Request though??
I tried it as T.J showed, and several other ways.
Firebug reported different errors.
Suggested method for inline returned (' missing } from property
statement') with parenthes ')' and
syntax errors without them.
Trying in other positions had similar errors..

One odd bit of behaviour noted though.
After populating the arrays and after exiting the Ajax.functions, when
I did 'alert(this.cap_questions) before the method finished only got a
blank result, not undefined, just blank.
I figured that self = this is like using the PHP  operator which
binds the new var to the original?
I even tried to alert(self.cap_questions) and got the same blank
result.
Yet, the arrays where populated as expected?? I guess part of the game
is having faith in what your doing!

I used the 'var self = this;'  Worked like a dream - thanks.

I did use the bind() in a few other places, like inside some
setTimeout's - where I wrap in a function() as per LINT methods..

I definately learnt a few new things tonight. Much appretiated. I
relate a lot to my PHP Classes and basic JS knowledge, but I'll have
to do some homework on Prototype Classes and Js Classes and Objects.
My Js function days are over. Classes from now on..

The second issue about calling one method from within another resolved
itself using the bind().

I also did a quick test, regarding what you said about 'global vars'.
I set a var in one method and tested for in in the next one that runs,
but it returned 'undefined'..
I did tidy up the vars as you suggested though!

I'll study the links that you gave me to see if I can undeestand how
globals (declared vars) run their scope in Js classes.
I think thats the key issue with all od this, scope..

I know that globals can be a bad thing as per ADSafe specs..

I'm going to be re-writing most of my JS into classes now, so you may
hear from me again on classes if I get stuck..

I have another problem with prototype that I want to ask about, but as
its not related so I'll start a new thread tommorow.
Its bedtime now here in Oz..

Thanks again for your prompt help. This is a great group.
Signing Off - 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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Using this.arrayname to add data to an array not working

2009-04-27 Thread T.J. Crowder

Hi,

Your Logger class, as given, will work fine:

var l = new Logger();
l.write(Testing);
l.write(One);
l.write(Two);
l.write(Three);

The result of the above would be that the 'log' array would be:

[Testing, One, Two, Three]

 I have had to use the following in my method that updates the array.

That workaround is not necessary.  If this code works:

var qArr = this.cap_questions;// create a var as the array //
for(blah blah){
var q = // set-up the value //
qArr.push(q);
}
this.cap_questions = qArr; // restore the classes array value with

...then this code works:

for(blah blah){
var q = // set-up the value //
this.cap_questions.push(q);
}

I suspect if you give us a more complete example -- including direct
quotes of where you're using your class (the above are clearly edited
examples) -- we'll be able to tell you what you're doing wrong.  My
guess would be that it relates to how you're calling your class's
instance methods.

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

On Apr 27, 2:05 pm, Imbi Rehling imbil...@tpg.com.au wrote:
 Hello to all, my first post to this group!
 I am new to OOP in JavaScript and have written my first Js Class using
 prototype.js..
 On the 'Learn pages' at prototypejs.org the example for
 'Classes-Inheritance' shows the following..

 var Logger = Class.create({
   initialize: function() {
     // this is the right way to do it:
 this.log = [];
   },
   write: function(message) {
     this.log.push(message);
   }

 });

 For some reason I can't seem to add to the array using 'this.arrayName'.
 I have tried also this.arrayName[i] = value;
 I initialize the array using the method shown above
 I have had to use the following in my method that updates the array. I have
 several methods that will update arrays, and will probably have to use the
 same in those. It will mean two lines of extra code for each method!!
 .

     var qArr = this.cap_questions;    // create a var as the array //
     for(blah blah){
         var q = // set-up the value //
         qArr.push(q);
     }
     this.cap_questions = qArr; // restore the classes array value with
 updated var //

 Does anyone have an explanation for this, or is it a bug??
 If its a bug, should it be reported at the site??
 Thanks in advance..  Gilbert
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Using this.arrayname to add data to an array not working

2009-04-27 Thread IMBI-Indie-Portal

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
-~--~~~~--~~--~--~---