mjmitche
mjmitche

Reputation: 2067

JavaScript XMLHttprequests

I got this example demonstrating AJAX from Stoyan Stefanovs Object Oriented JavaScript at page 275. In this example, he is requesting three different files. I have a couple questions if any of you can help.

  1. What is xhr.send('') doing? Why do we need it? I thought GET in the line before was establishign contact with the server, so why this send?
    (The other questions relate to the closure that I don`t fully understand...)

  2. what exactly is getting passed as a paramater to function(myxhr)?

  3. regarding the anonymous function, which has (xhr) passed as a parameter, can you explain at what point in the program xhr gets passed to the anonymous function? For example, is it after xhr.open has taken place?

  4. why is function(myxhr) necessary? If it`s to create closure, why is closure necessary here?

  5. is parameter (xhr) of the anonymous function getting passed as parameter myxhr in function(myxhr) once the anonymous function is called?

  6. if 5 is true--that xhr is passed as a parameter to function(myxhr)--why is it necessary to change the parameter name from xhr to myxhr?

Sample code:

function request(url, callback){
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = (function(myxhr){
    return function() {
      callback(myxhr);
    }
  })(xhr);
  xhr.open('GET', url, true);
  xhr.send('');
}

request (
  'http://www.phpied.com/files/jsoop/content.txt',
  function (o){
    document.getElementById('text').innerHTML = o.responseText;
  }
);

request(
  'http://www.phpied.com/files/jsoop/content.html',
  function(o) {
    document.getElementById('html').innerHTML = o.responseText;
  }
);

request(
  'http://www.phpied.com/files/jsoop/content.xml',
  function(o){
    document.getElementById('xml').innerHTML =
    o.responseXML.getElementsByTagName('root')[0].firstChild.nodeValue;
  }
);

Upvotes: 1

Views: 2052

Answers (3)

Tomalak
Tomalak

Reputation: 338118

1 - What is xhr.send('') doing?

It sends the request to the server. No network activity occurs before send() is called.

1.a - Why do we need it? I thought GET in the line before was establishing contact with the server, so why this send?

Because open() does not communicate with the server. It merely prepares the request object.

2 - what exactly is getting passed as a paramater to function(myxhr)?

The object xhr is passed to that function.

(function(myxhr){ /* ... */ })(xhr);
//-----------------------------^^^
//  define the function...    | ...and call it immediately

3 - regarding the anonymous function, which has (xhr) passed as a parameter, can you explain at what point in the program xhr gets passed to the anonymous function? For example, is it after xhr.open has taken place?

It gets passed immediately. The function(myxhr) has no other purpose in life than constructing and returning its result (which just happens to be another function), so its entire lifetime is the single statement in which it is defined and called immediately.

4 - why is function(myxhr) necessary? If it`s to create closure, why is closure necessary here?

In fact, the extra closure is not necessary. It's superfluous. This is equivalent (and it also creates a closure):

function request(url, callback){
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = (function() {
      callback(xhr);
  });
  xhr.open('GET', url, true);
  xhr.send('');
}

The closure is necessary so the callback function which is registered to the readystatechange event has some context to run in. A closure is always created automatically whenever a function is defined. It preserves the variables that were in scope at the time the function was defined: The above preserves the meaning of xhr and callback (and url, too!) in the inner function, even though it is not clear when the callback function is going to be executed.

5 - is parameter (xhr) of the anonymous function getting passed as parameter myxhr in function(myxhr) once the anonymous function is called?

Yes, it is passed when the anonymous "outer" function is called (see 3).

6 - if 5 is true--that xhr is passed as a parameter to function(myxhr)--why is it necessary to change the parameter name from xhr to myxhr?

It is not necessary, but less confusing than using the same variable name everywhere. Compare:

var f = (function(i) {
  /* outer scope i = 4 */
  return (function(i) {
    /* inner scope i = 8 */
    return i;
  })(i + 4);
})(4);

// now f is 8

However, if you want to use the "outer" i in the "inner" function, you'd have to use something else than i as the parameter name for the inner function.

Upvotes: 1

Furqan Hameedi
Furqan Hameedi

Reputation: 4400

A helpful resource to understand this is XMLHHTPRequest Object from MSDN and Using XMLHTTPReuqestobject, but for brevity I try to answer your questions shortly.

  1. xhr.send() ; issues the request to the URL through Open method.
  2. XMLHTTPRequest object is passed as function parameter function(myxhr)
  3. 'xhr' gets passed to the function when the request's status is changed after some response is received.
  4. 'myxhr' is only the name of paramter that you can change as u wish but the object passed is of type XMLHttpResponse.
  5. Yes
  6. It is not necessary at all.

Upvotes: 1

Quentin
Quentin

Reputation: 943097

What is xhr.send('') doing? Why do we need it? I thought GET in the line before was establishign contact with the server, so why this send? (The other questions relate to the closure that I don`t fully understand...)

Open just sets up the request. Send actually sends it. When you make a POST request you need to pass the to send.

what exactly is getting passed as a paramater to function(myxhr)?

The content of the variable xhr.

regarding the anonymous function, which has (xhr) passed as a parameter, can you explain at what point in the program xhr gets passed to the anonymous function? For example, is it after xhr.open has taken place?

As soon as the function is called (which is immediately as the definition is followed by ()).

why is function(myxhr) necessary? If it`s to create closure, why is closure necessary here?

It isn't. Even if the xhr variable wasn't locally scoped to the request function (which it is) then it could be accessed via this.

is parameter (xhr) of the anonymous function getting passed as parameter myxhr in function(myxhr) once the anonymous function is called?

Yes.

if 5 is true--that xhr is passed as a parameter to function(myxhr)--why is it necessary to change the parameter name from xhr to myxhr?

It isn't. You can reuse the variable name at different scopes. It makes it less confusing though.

Upvotes: 2

Related Questions