0

I am new to jQuery and I am trying to build something with AJAX. I tried to use the normal, basic XMLHttpRequest class and then $.ajax({...}) but none of them work.

function getNormal_XHR_Request(){
    let request = new XMLHttpRequest();

    // I also tried to make a variable here, assign it to the request.response and return it in the end
    let returnValue = null;

    request.addEventListener(
        "load",
        (event) => {
            if(request.readyState === 4 && request.status === 200){
                console.log(request); // this will work
                console.log(request.response); // this will work too
                // Assign the returnValue to the request.response
                returnValue = JSON.parse(request.response); // JSON.parse(request.response) doesn't return undefined, it returns my object that I want to use, but even if I equal the returnValue to it, it will still return undefined
                return JSON.parse(request.response);
            }
        },
        false // dispatch event in the bubbling phase not in the capturing phase
    )

    request.open("GET", "scripts/users.json");
    request.setRequestHeader("Accept", "text/json");
    request.send();

    return returnValue
}

This is the normal XMLHttpRequest() that I used. The problem is, that if I want to say for example

x = getNormal_XHR_Request()

so that I would have the JSON file in my x variable, it doesn't work and it returns undefined.

And the exact same things happens with $.ajax({...})

class XHR_REQUEST{
    constructor(path){
        this.path = path;
    }
    getRequest_XHR(requestHeaders){
        this.requestHeaders = requestHeaders;

        var self = this;
        let returnValue = [];

        $.ajax({
            url : self.path,
            dataType : "json",
            headers : self.requestHeaders, 
        })
        .done((data) => {
            returnValue = data;
        })
        .fail((jqXHR, errorMessage, error) => {
            console.log(jqXHR);
            console.log(errorMessage);
            console.log(error);
        });

        return returnValue;
    }
};

It works the same as the normal function that I used above, everything that I do, returns undefined, even if request.response gives me the correct answer. If I try to console.log(request.response), I will get the object, if I try to return it and console.log() the result, it will give me back undefined. Why ?

isherwood
  • 58,414
  • 16
  • 114
  • 157
David
  • 624
  • 1
  • 6
  • 21
  • What does `requestHeaders` look like? – Taplar Jan 28 '20 at 20:02
  • {"Accept: "text/json", "Content-Type" : "application/json"} – David Jan 28 '20 at 20:04
  • 1
    The problem there is that you are willing to return a value from an asyncronous call. The returnValue there will always come up emtpy. – MarkSkayff Jan 28 '20 at 20:16
  • Yeah, but what why does it return undefined after the request.readyState is 4, so it's loaded and the status is 200 so it's "OK", that doesn't make sense anymore I think, because the request is loaded and everything works fine, so I return that after everything is loaded. If I print it, it gives me the right answer otherwise, if I try to return it, it will give me undefined. So, if I would just return the value after it's loaded, without using other variables, why does it still return undefined after it's loaded ? – David Jan 28 '20 at 20:18
  • @DavidGugea That's because all that is happening asynchronously David. Check my answer below. – MarkSkayff Jan 28 '20 at 20:25
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – James Jan 28 '20 at 23:14

1 Answers1

1

The result you are getting in both examples is completely normal. The reason you are getting an undefined value is because both requests are happening asynchronously. The correct place where to return something or take some action with the results you get are:

1) request.addEventListener('load', event => {} .... within the event here you can perform the action on a succesfull response.

2) with the $.ajax() call you do it within the done() promise handler.

Those are the right places to take proper action on the results. You have to modify your mindset to start using the responses from the asynchronous callbacks.

The problem there is that you are returning the result, even before the callback has some value filled in the variable.

There are new constructions this days to make asynchronous calls behave synchronously withe async-await constructions. But besides this I think you have to modify or adjust your code to react to the async results in a way it works.

MarkSkayff
  • 1,334
  • 9
  • 14