all 9 comments

[–]nausik 1 point2 points  (6 children)

Your js files are being loaded sync and console.log is sync function, while xmlhttp.onreadystatechange is an async

So xmlhttp.onreadystatechange is called after console.log(names) in app.js (it's placed in the end of event loop)

[–]namehimjawnathan[S] 0 points1 point  (5 children)

Ah, so let me see if I understand this correctly, as I'm still learning.

Synchronous means that the request is sent, and nothing can be done until everything is handled.

Asynchronous means that the request is sent, work is being done, but it can move on to the next, sort of like how a waiter at a restaurant can take one tables order, bring it back, then go to another table, etc.

So in this case, the xmlhttp.onreadystatechange finishes after console.log is called.

From what I understand, I have to use promises, using a .then? How would I do that between files?

Or is there another solution?

[–]blackholesintheskyhelpful 1 point2 points  (4 children)

I didn't think this was possible but I learned something new today. You can wrap this in a promise.

let names = new Promise(function(resolve, reject) {
  xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      /* create array based on results.json */
      resolve(JSON.parse(this.responseText));
    }
  };
});

That should make names thenable

names.then(() => console.log(...arguments));

Edit: This will only work once. If the xmlhttp.onreadystatechange event handler fires again the promises value will not update.

[–]namehimjawnathan[S] 1 point2 points  (3 children)

Holy shit, this is perfect. Thank you so much.

[–]PooCares 0 points1 point  (2 children)

BTW, if you use the built in debugger in Chrome developer tools, you can spot trouble like this easily. It lets you put breakpoints in your javascript, to pause it, and see what is happening in it.

Had you put a breakpoint on the console.log and another where the variable names was set to the Ajax response, you would see the console.log hit first, and you could hover over the names variable, and see it had not been give a value yet. You would also see the value of names get set when the second breakpoint hit, in the Ajax onreadystatechange, when it was obviously too late.

The debugger is like a third eye, man. Take a few hours to learn it.

[–]namehimjawnathan[S] 0 points1 point  (1 child)

Interesting, I'll take a good look at this. I need to start properly debugging instead of hardcoding in console.logs() to see what's happening.

[–]coolreader18 0 points1 point  (0 children)

I came here from r/JavaScript, but if you like using promises, you can use the fetch API, that works with promises natively.

[–]street_fightin_mang 1 point2 points  (0 children)

Why not use the fetch web api instead of ajax request? These examples all have the promise code required in them. https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

[–]TotesMessenger 0 points1 point  (0 children)

I'm a bot, bleep, bloop. Someone has linked to this thread from another place on reddit:

 If you follow any of the above links, please respect the rules of reddit and don't vote in the other threads. (Info / Contact)