views:

36

answers:

1

Hello. I am new to AJAX and have this issue.

I am creating a photogallery page and on it I created a Javascript class which manager the whole thing. Here is a method from the class which calls XMLHTTPRequest object which was initialized successfully earlier:

this.AJAX_update = function(id) {
    //initialize AJAX - this is done successfully
    this.AJAX_initialize();
    var url = "ScriptLibrary/gallery_update.php?img=" + id;
    //this.ajax_request is an internal variable which is
    //initialized in this.AJAX_initialize() and is
    //XMLHTTPRequest type
    this.ajax_request.open("GET", url, true);
    this.ajax_request.onreadystatechange = processAJAX;
    this.ajax_request.send(null);
}

I could not figure out how to call class' internal method in onreadystatechange, so I created a function outside of the class which calls a method inside the class provided that the instance of the class has been created on the page which it is. The instance of the class on the page is the variable 'gallery'. Here is the function:

function processAJAX() {
    gallery.AJAX_process();
}

Here is the code of the AJAX_process() function:

this.AJAX_process = function() {
    if (this.ajax_request.readyState == 4) {
        if (this.ajax_request.status == 200) {
            //get the response
            var response = this.ajax_request.responseXML;

            //Here I set the internal variables according to the value
            //returned from the server
            //...........
            //...........
            //...........

            //change image on the page
            var self = this;
            setTimeout(function() {
                self.swap_dissolve();
            }, 50);

        }
    }
}

So, here is my question:

Initially I tried to call the internal function directly by just doing this.swap_dissolve() however it does not work. Basically the AJAX_process() method changes values of certain class' internal variables according to the response from the server, and those values are used in the swap_dissolve() to actually change the image on the page. What would happen is that swap_dissolve() would not change the image correctly because it was seeing null or not updated values of the variables AJAX_process() updated. When I added the time delay, the problem disappeared. I don't understand why that is happening. I do check that the readyState == 4, so the response from the server has been completely returned, therefore whatever values the function sets, are final and can be used right away, so why can't I use those values right away and have to wait?

Any suggestions or faults in my code to resolve this issue would be highly appreciated.

If you have any question to me, please post response to this question.

Thank you.

A: 

You want to use a 'closure' (e.g. pass a function-object to setTimeout).

Imagine this (heck, substitute it in your code to see):

// when response = 200
var someValue = "blahblah" // whatever you read in
setTimeout(function () {
  alert(someValue)
}, 1000)

The alert should display "blablah" (or whatever you assigned to it). The value is available to the anonymous function object because a closure-binding has been created (the function can access the variables of the enclosing function scope(s).

Here is a reference: http://jibbering.com/faq/notes/closures/ and more of a soft intro: http://blog.morrisjohns.com/javascript_closures_for_dummies.html

Happy coding.

Edit/P.S. You can also write the AJAX handler like (it's just a closure to force the correct 'this' context -- some frameworks offer convenience functions for this):

var self = this
this.ajax_request.onreadystatechange = function () {
   self.process_AJAX()
}

You can even use a double-binding, but... happy coding, again :-)

pst
Thank you for the suggestion. I did not you can do that. This however still does not fix the issue. I still have to wait. What causes the swap_dissolve() not to work right away?
miki725
@miki725 Now, what values do you not see updated?
pst
I just implemented your last suggestion regarding the onreadystatechange = function()... and that seemed to solve the issue. Thank you very much.
miki725
What was happening before is that the swap_dissolve() was not seeing the variable values process_AJAX() updated. Apparently calling the process_AJAX() the way you suggested fixes the issue.
miki725