Search code examples
javascriptasynchronousxmlhttprequest

How to return a value in asyncronous xhr request?


How would I return loadFile.responseText as the return value in xhr() function where loadFile.Open is set to true (async)... When I set the request as synchronous (false), the value is returned. I do understand why this happens but I am wondering if there is a way to accomplish this with asynchronous settings.

loadFile.open("GET", url, true); // no response

Whole function:

function xhr(url, async){

    var data = '';

    var loadFile = new XMLHttpRequest();

        loadFile.overrideMimeType("application/json");

        loadFile.open("GET", url, false); // when true, no value is returned (of course)

        loadFile.onreadystatechange = function() {

            if (loadFile.readyState === 4 && loadFile.status == "200")
            {
                data = JSON.parse( loadFile.responseText );

                return data;
            }
        }

        loadFile.send(null);

    return loadFile.onreadystatechange();
}

I was looking for an answer to this and found this How do I return the response from an asynchronous call? and it is NOT a duplicate.

I don't mind entirely changing the direction if it is required. Can you help with an actual basic example or a solid suggestion of which way to go to accomplish that?


Solution

  • I am going to answer this then close this as a duplicate. This answer is purely a clarification for your SPECIFIC problem. The real answer is to read and understand the duplicate.

    Here I'm going to copy and paste the relevant portion from the duplicate answer:

     var result = foo();
     // Code that depends on 'result'
    

    becomes

     foo(function(result) {
         // Code that depends on 'result'
     });
    

    So your code should be restructured as:

    function xhr(url, callback){
    
        var data = '';
    
        var loadFile = new XMLHttpRequest();
    
            loadFile.overrideMimeType("application/json");
    
            loadFile.open("GET", url, false); // when true, no value is returned (of course)
    
            loadFile.onreadystatechange = function() {
    
                if (loadFile.readyState === 4 && loadFile.status == "200")
                {
                    data = JSON.parse( loadFile.responseText );
    
                    callback(data); //// NOTE: this is how you return the value
                }
            }
    
            loadFile.send(null);
    
        loadFile.onreadystatechange();
    }
    

    And how to use the returned result:

    xhr(some_url, function (result) {
        // use result here
    
        // NO, it's not possible to get result outside this function
        // If you really want you can pass it further to other functions:
    
        do_something_with(result);
    
        // but you can NEVER return it
    });
    

    Basically you need to restructure your code and get used to callbacks.

    There are fancier ways to do callbacks like promises and with newer versions of js async/await (which returns promises) but they're all callbacks nonetheless.