Hi Nate,

First of all, thank you very much for taking the time to respond.  It's 
greatly appreciated.

I had to modify your solution slightly, in that the ajax.complete 
callback passes two parameters which I need, so I changed the code to...

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(ajaxResponse, status){
            instance.parseXML(ajaxResponse, status);
        }
    }
);

This works just fine, and I thank you once again.  I'd never have worked 
this out using the books I have.

I have to admit though, I still don't fully understand the mechanism 
going on here.  If anyone is aware of any on-line resources that go into 
detail about the scope of 'this', I'd be grateful.

You mention the phrase "you can use a closure", is this a common term in 
Javascript? What does it mean?

Once again, thank you.

Regards,

Glenn



Nate Cavanaugh wrote:
> 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
>>
>>
>>
>>     
>
>   

Reply via email to