0

Well here's my problem. I have a function that is supposed to get a file and return the contents, cause my host provider doesn't let me use PHP.

function getStoryFromFile(file){
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (xhttp.readyState == 4 && xhttp.status == 200) {
            return xhttp.responseText;
        }
    };
    xhttp.open("GET", file, true);
    xhttp.send();
}

And then I discovered that anonymous functions don't work like that. So then I tried to make it work by making it do this.

function getStoryFromFile(file){
    var xhttp = new XMLHttpRequest();
    var x = 'false';
    xhttp.onreadystatechange = function() {
        if (xhttp.readyState == 4 && xhttp.status == 200) {
            x = 'true';
        }
    };
    xhttp.open("GET", file, true);
    xhttp.send();
    if (x == 'true'){
        return xhttp.responseText;
    }
}

But that didn't work either. So I've tried to tweak it for hours and nothing's worked. All that I get is 'undefined'. So can somebody please explain to me why Javascript won't allow me to return the content the second way and why the developers of javascript made the language so goddamned difficult to understand. Thank you.

EDIT How do you get the callback function to write to a variable? I have:

function displayPage(){

file = 'story1.html' //Not actually like this in file, it changes based on database but i simplified it
var toHTML = '';
getStoryFromFile(file,function(text){
toHTML += text + "<br>";
});
document.getElementById('div').innerHTML = toHTML;
}

The anonymous function doesn't write even though it's global. Thats the main problem now

  • *"why the developers of javascript made the language so goddamned difficult to understand"* - As with any programming language you need to actually take some time to learn how it works. The problem you have relates to asynchronous functions, a concept that doesn't apply in some other languages, so maybe Google up a tutorial about that and go from there. – nnnnnn Jul 03 '16 at 00:07
  • [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) is a newer way... – Ronnie Royston Jul 03 '16 at 00:10
  • The linked duplicate question does have some jQuery content, but the accepted answer has a good explanation of this issue with asynchronous functions and does cover some plain JavaScript (non-jQuery) techniques, and [this answer](http://stackoverflow.com/a/16825593/615754) is all plain JavaScript. [This question](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) also has some useful reading for you. – nnnnnn Jul 03 '16 at 00:14

1 Answers1

1

No, none of that will work because it is an asynchronous call (nothing to do with anonymous functions). The right thing to do is to provide a callback function instead.

function getStoryFromFile(file, callback){
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (xhttp.readyState == 4 && xhttp.status == 200) {
            callback(xhttp.responseText);
        }
    };
    xhttp.open("GET", file, true);
    xhttp.send();
}

getStoryFromFile('someFile', function(text){
    // do something with the responseText.  let's console.log it:
    console.log(text);
});
John Green
  • 13,241
  • 3
  • 29
  • 51
  • The second argument is the callback function. This is an anonymous function / closure. The issue is that since the AJAX request gets sent out, you don't know when it will return... it may be 20ms, it may be 5s... if you block the rest of execution waiting for the return, you're likely to break other parts of your app. You *can* set it to be a synchronous call, but that's rarely recommended. Instead, you provide a function which gets called once the Ajax call has completed... in this case, a function that console.logs the response. – John Green Jul 03 '16 at 00:10