eoligarry (3) [Avatar] Offline
#1
Hi,

This is an excellent book. I've really enjoyed it and learned a lot.

I'm trying to create an Object that can update itself via an Ajax request. I'm using the Prototype library instead of the ContentLoader because everything else on my page is using Prototype.

What I want is to be able to get a reference in the callback function to the Object that called that function, and the problem I am having is that the "this" variable in that context refers instead to the Ajax.Request object that called it.

I.e., here's a snippet of my code:
var myOBJ = new Object();
// avoid namespace collisions by putting everything into myOBJ
myOBJ.content_object = function(id, content_type) {
this.id = id;
this.content_type = content_type;
this.url = this.defaultURL;
this.AJAXMethod = this.defaultAJAXMethod;
}
myOBJ.content_object.prototype = {
getParams:function() {
return 'foo=1&bar=2';
},
defaultURL:'/ajax/loadContent.php',
defaultAJAXMethod: 'get',
onComplete: function(x) {
alert(this.id); // "undefined" b/c "this" doesn't reference this object, it references Ajax.Reqest
},
reload:function() {
var myAjax = new Ajax.Request(
this.url,
{
parameters: this.getParams(),
method: this.AJAXMethod,
onComplete: this.onComplete
}
);
}
}

var main = new myOBJ.content_object('main_div', 1);
main.reload();
var sidebar = new myOBJ.content_object('sidebar_div',2);
sidebar.reload();



================
additional comment:

I wasn't sure that this was possible until I saw how, on page 75 of my Ajax in Action book, the ContentLoader object is able to pass "this" as an argument to the onerror or onload functions. But I cannot for the life of me figure out how I could use that in the case where I'm using the Ajax.Request object from the prototype library. Many thanks in advance for your suggestions.

Message was edited by:
eoligarry
Pascarello (208) [Avatar] Offline
#2
Re: Using "this" to reference parent object in an Ajax callback method
Set a local variable inside of the function/method

myOBJ.content_object.prototype = {
var ref = this;

so when you want to reference it it would look like

alert(ref.id)


Eric
eoligarry (3) [Avatar] Offline
#3
Re: Using "this" to reference parent object in an Ajax callback method
Eric,

Thanks for the tip.

Unfortunately, I'm still having some trouble. I added the line "var ref = this;" as the first in the definition of the reload() function. So this part:

reload:function() {
this.overlay();
....
var myAjax = new Ajax.Request( ...

became like this:

reload:function() {
var ref = this;
this.overlay();
...
var myAjax = new Ajax.Request( ...

And I changed the first line of the onComplete function to be "alert(ref.id);", but that was failing, so I put it in a try catch block like this:
try {
alert(ref.id);
} catch (error) {
var error_str = '';
for (var i in error) {
error_str += i + ': ' + error[i] + '
';
}
alert(error_str);
}


And the error alert that I got is this:
"message: ref is not defined
fileName: http://localhost/test
lineNumber: 2490
stack: ([object XMLHttpRequest],null)@http://localhost/test:2490 (4)@http://localhost/js/prototype.js:765 ()@http://localhost/js/prototype.js:724 apply([object Object],[object Array])@:0 ()@http://localhost/js/prototype.js:48 @:0
name: ReferenceError"

I also tried a couple other methods of setting the "ref" variable, including adding a line "ref:this," in my JSON notation for the prototype of the object, and including the line:
"OI.content_object.prototype.ref = this;"

But those didn't help either. Any further tips? I was thinking that I could just include "ref_id: this.id" as a line in one of the options for the Ajax request (along with method: and paramssmilie, but that seems really hacky...

thanks!
Cory



> Set a local variable inside of the function/method
>
> myOBJ.content_object.prototype = {
> var ref = this;
> so when you want to reference it it would look like
>
> alert(ref.id)
>
>
> Eric
kurinosuke (156) [Avatar] Offline
#4
Re: Using "this" to reference parent object in an Ajax callback method
I think that you've already tried this, but can you confirm that the following doesn't work either ?
onComplete: function(x) {
alert(this.parent);
},
reload:function() {
var myAjax = new Ajax.Request(
this.url,
{
parameters: this.getParams(),
method: this.AJAXMethod,
onComplete: this.onComplete,
parent: this
}
);
}
eoligarry (3) [Avatar] Offline
#5
Re: Using "this" to reference parent object in an Ajax callback method
I did try using this.parent, but you're right, that didn't work either.

In Safari, alert(this.parent) said "[object window]" and in Firefox 1.5 it said "undefined".

I've implemented a workaround to fix the problem for now. What I do is I send the ID as a parameter in the AJAX request, and the PHP page that handles the query just returns the ID in a JSON object. Not elegant but it's working.

I'm still interested in hearing of a better way, though! I'm sure it's possible.

thanks,
Cory
kurinosuke (156) [Avatar] Offline
#6
Re: Using "this" to reference parent object in an Ajax callback method
I'm not sure this makes any difference but try with a closure:

var oThis = this;
var myAjax = new Ajax.Request(
this.url,
{
parameters: this.getParams(),
method: this.AJAXMethod,
onComplete: this.onComplete,
parent: oThis
}
);