Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Loosing access to 'this' objects in callback method!

Status
Not open for further replies.

knnelg

Programmer
Jun 23, 2007
1
GB
Hi, I'm a newbie to javascript and I'm also using jQuery so I'm not sure if my issue is jQuery or JavaScript.

The issue is that I'm creating a constructor for an object, in which I
initialise some instance properties, then kick off an asynchronous
$.ajax event to retrieve an XML file. The callback method of
the .ajax object is bound to a prototype method of the same object as
the constructor.

My problem is that when the ajax call is complete and the callback
method is called, it appears that the callback method cannot see any
of the 'this'.properties that were initialized in the constructor.

I'm beginning to think that the asynchronous nature of the ajax object
has actually created a new instance of my object in which no
constructor was called and therefore is not working against the
original instance I created. But then again I always look for the
most obscure explanation instead of noticing the simple error I've
made.

I've included the code below. If anyone can show me the errors of my
ways, I'd be very grateful.

The line causing me a problem is commented with // THIS LINE FAILS
WITH AN "this.woffers has no properties" ERROR

================================================================
// Use jQuery 'document.ready' selector to define the function to call
when page is ready.
$(main);

//////////////////////////////////////////////////////////////////////////////
// The main entry function hopefully called by the jQuery 'ready'
selector
//////////////////////////////////////////////////////////////////////////////
function main() {

try {
//create a new 'Woffers' instance
var woffers = new Woffers("woffersdata.xml", "xml");
}

// Catch any exceptions...
catch(e) {

// ...and report them. TODO: remove this for live
alert(e);

}

}

//////////////////////////////////////////////////////////////////////////////
// Constructor for a 'Woffers' class which will contain all our
'Woffer' items
// and some methods to retrieve them.
//
// Expects:
// sourceURL - a String containing the location of the file containing
the
// data to be used to construct our object.
// sourceType - a String containing the type of file we are using to
// construct the object. Can be "xml" or "json"
//////////////////////////////////////////////////////////////////////////////
function Woffers(sourceURL, sourceType) {
if(sourceType != "xml") {
throw new Error("Invalid source type (" + sourceType + ") supplied
to Woffers constructor.");
}

// Store parameters for later use by any method
this.sourceURL = sourceURL;
this.sourceType = sourceType;

// Create a property to hold a list of Woffer objects
this.woffers = new Array(); // <-- This property should get populated
by the $.ajax callback method

switch(this.sourceType) {
case "xml": {
$.ajax(
{
type: "POST", // type of http request
url: this.sourceURL, // where to get file from
dataType: "xml", // type of file to retrieve
complete: this.parseXML // Function to run on completion which
will populate this.woffers
}
)

break;

} // End case(xml)

case "json": {
$.ajax(
{
type: "POST", // type of http request
url: this.sourceURL, // where to get file from
dataType: "json", // type of file to retrieve
complete: this.parseJson // Function to run on completion
}
)

break;

} // End case(json)
}

} // End Woffers constructor

//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
Woffers.prototype.parseXML = function(woffersDOM, resultStatus) {
if(resultStatus != "success") {
throw new Error("Encountered a problem retreiving the XML file." +
" Reported status is " + ResultStatus + ".");
}
// retrieve a list of woffers from the response
var retrievedWoffers =
woffersDOM.responseXML.documentElement.getElementsByTagName("route");

// Go through each woffer and use it to create a new 'Woffer' object
for(var index = 0; index < retrievedWoffers.length; ++index) {

//
// THIS LINE FAILS WITH AN "this.woffers has no properties"
ERROR
//
// Create a new woffer and add it to 'this.woffers'
this.woffers.push(new Object());

}

}


Any feedback, much appreciated

Regards,

Glenn
 
I just was trying to figure out the same problem with a callback from an interval. By coincidence I tried to figure out how to solve it by checking how JQuery works around this problem in their animate and ajax functions. But couldn't figure out why their method would work better.

So instead I used a function I also use for my event callbacks:

var classBind = function(instance, method) {
return function() {  
return method.apply(instance, arguments);  
}
}


in your example

complete: this.parseXML

becomes then

complete: classBind(this, this.parseXML)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top