0

I'm new to JavaScript and have run into an issue in calling the XMLHttpRequest function.

My code is as follows:

document.addEventListener('load', loadJsonFile(), false);

function reqListener() {
    var obj = JSON.parse(this.responseText)

    //Send for the html of a generic post
    var reqObj = new XMLHttpRequest();
    reqObj.onload = buildProjects(reqObj, obj);
    reqObj.open("get", "post_box.html", true);
    reqObj.send();
}

function buildProjects(reqObj, data){

    for(var i = 0; i < 5; i++){
        

        html = reqObj.responseText;
        console.log("data is: " + data.title);
        console.log("State: " + this.readyState);
        console.log("Request object is: " + reqObj);
        console.log("Response is: " + reqObj.response);
        console.log("html is: " + html);
    }
}

//Load all project data
//Then call reqListener function
function loadJsonFile(){
    var reqObj = new XMLHttpRequest();
    reqObj.onload = reqListener;
    reqObj.open("get", "test.json", true);
    reqObj.send();
}

I expected calling 'this' in the buildProjects() function would return the calling XMLHttpRequest object. This does not happen. Instead a 'Window' object is returned.

I tried working around this by passing the reqObj as parameters but this doesn't work either. I'm guessing this is a scope issue ?

I don't have any idea why the call to 'this' doesn't work. Calling 'this' works for me when I have a single XMLHttpRequest.onload function called, so I'm led to thinking it's something to do with nesting a request within a request ?

I've seen a similar question asked regarding functions called using arrow notation but I can't see how the answer there answers my problem.

Help is appreciated,

Thanks

UPDATE:

I managed to fix my issue by tagging .bind() to the end of a function call. This forces the keyword 'this' to be whatever value is passed in the bind() parameters. Thanks for the comments to point this out.

While my problem is fixed in this case, I still don't understand what went wrong originally. As I say, I'm fairly new to JS - a more detailed explanation would be appreciated !

Thanks again

DevJoe
  • 15
  • 3
  • You're calling `buildProjects` right away, then assigning the result of the function (undefined) to `reqObj.onload`. Use `reqObj.onload = buildProjects.bind(reqObj, reqObj, obj);`, but I don't think you need to use `this` inside `buildProjects` anyways. – kelsny Mar 19 '23 at 15:41
  • Is it not the case that the order of calling is: document_eventListener --> loadJSONFile --> requestListener --> buildProjects ? Why is 'this' treated differently in requestListener and buildProjects ? – DevJoe Mar 19 '23 at 16:00
  • You aren't calling `requestListener` in your code, but you *are* calling `buildProjects` – kelsny Mar 19 '23 at 16:02
  • This: `document.addEventListener('load', loadJsonFile(), false);` **calls** the `loadJsonFile()` function and passes the value it returns to `addEventListener`. That's an extremely common mistake. What you want to pass is just the reference to the function, so `loadJsonFile` without `()`. – Pointy Mar 19 '23 at 16:02
  • Same goes for `buildProjects()`, as others have noted. – Pointy Mar 19 '23 at 16:04
  • I've attempted running the script using loadJSONFile() without the parentheses. This doesn't call reqListener. – DevJoe Mar 19 '23 at 16:19

0 Answers0