Hi Glenn,
Keeping scope is definitely one of the more frustrating aspects of
Javascript sometimes.

What's happening is that you're running the ajax call, and the complete
method is a method of the object that you're passing into the ajax handler.

So this now points to the object containing the properties you sent in.

To do this so that your member method (the this.parseXML) retains the proper
scope, you can use a closure. I also like to always start off my methods
with a var declaration pointing to the instance this (so I always know when
I am pointing to the instance, and when I use this, that I am pointing to an
element, such as in an event call back):

var instance = this;

$.ajax(
{
type: "POST", // type of http request
url: this.sourceURL, // where to get file from
dataType: "xml", // type of file to retrieve
complete: function(){
instance.parseXML();
}
}
);

Now your parseXML method will run in the proper scope.

I hope that helps :)


knnelg wrote:
> 
> 
> Hi,  I'm another newbie to jQuery and also not that experienced in
> JavaScript 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
> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Loosing-access-to-%27this%27-objects-in-callback-method%21-tf3970581s15494.html#a11271667
Sent from the JQuery mailing list archive at Nabble.com.

Reply via email to