0

For the most part my code is working, but I'm apparently misunderstanding something about AJAX or and/or how to have the response data stored in the variable as I want.

var stored_data = getData(url, function(data){
  return data;
});

I'm expecting stored_data = data, but that's not happening. If I replace return data with console.log(data), it's clear that I am receiving the data I expected.

I'm a bit confused why data is not being assigned to stored_data

function getData(source, callback) {
    var xhr = new XMLHttpRequest();
    var result= '';

    xhr.open("GET", source);
    xhr.responseType = "document";
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200){
            result = xhr.responseXML.getElementsByTagName('pre')[0].innerHTML;
            callback(result);
    }
  }
  xhr.send();
}

Am I doing this correctly in order to set the value of stored_data, to the results of the AJAX request?

NOTE: I asked this question AFTER reading the one I'm asserted as DUPING. The other question has a lot of conceptual detail. MY question is really simple, in terms of what I am attempting to resolve.

What am I misunderstanding about assigning the value of a function calls results to a variable? It feels like it's something ridiculously simple, and I'm not seeing it.

Apparently, I'm confusing something about variables and function assignment.

E.g.

var somevariable = sum(9,1);

function sum(a, b){return a + b}

console.log(somevariable) // returns 10

So, with that understanding, If I call my getData function and assign it to a variable The data should land in that container right?

And using a callback is fine if I console.log() But I can't use the info if it's logged to console.

So am I misunderstanding variable = synchronous_result versus variable = async_result

How is it that I can have my variable resolve to the retrieved result from an async call, using VANILLA JS and a callback? What am I misunderstanding, and how do come to an understanding of what seems like a very simple question?

I comprehend asynchronous. So how do I get the data to resolve? I don't need anything done to the data other than to retrieve it, and then store it?

RESOLUTION: FOR THE SAKE OF OTHERS HAVING A SIMILAR MISUNDERSTANDING Borrowing off the concept in the post that this one is purportedly duplicating:

I have an object with a property that I want to populate with data from a URL. This requires an AJAX operation.

datastore.info is the property and object.

The resolution was in this code singature:

datastore.info = getINFO(url, function(data){datastore.info = data;});

That's it.

For me it is counter-intuitive. I was expecting the function call to result in a value, but with asynchronous code, the assignment does not occur as a result of the function call. It is a delayed action that comes from the asynchronous step.

As a result, the assignment occurs when the callback is asserted. This logic is counter to synchronous coding, and it took this particularly simple exercise to see that clearly.

Self-learning is a bitch when the help you think you have is not actually there. But spending 8 hours sussing out a one-line problem does make one appreciate their own persistence.

Figuring this out helped me "level up" on the concept of callbacks, asynchoronous operations, and promises as a powerful tool for "out of time" actions.

Ken Ingram
  • 1,538
  • 5
  • 27
  • 52
  • 1
    AJAX is asynchronous, so the code will continue (return from `getData`) before the callback is ever called. You will need to do whatever you want from the callback (or call the functions you need to be executed from there). Or use `async`/`await` as explained in the dupe. – Ivar Mar 22 '19 at 20:38
  • 1
    *"I'm a bit confused why data is not being assigned to stored_data"* Aside from Ajax being asynchronous, `var stored_data = getData(...)` means that the return value of `getData` is assigned to `stored_data`. Looking at the implementation of `getData` we see that it doesn't return value. It does not contain a `return` statement. Now, adding `return result;` at the end won't work since Ajax is asynchronous, which is why you have `callback` in the first place. – Felix Kling Mar 22 '19 at 20:41
  • I know it's asynchronous. It's why I'm using a callback. What can you tell me that I'm missing? – Ken Ingram Mar 22 '19 at 20:45
  • 1
    *"I know it's asynchronous. It's why I'm using a callback."* And yet you expect that `getData` somehow returns the data. That's not possible. A function always returns synchronously. And since `getData` doesn't have a `return` statement, it returns `undefined`. Not sure how else to explain it... – Felix Kling Mar 22 '19 at 20:49
  • I want to assign the value from the function to the variable. How did I make that a mystery. I read the dupe BEFORE I asked the question. I want to understand using Vanilla JS. I'm mistranslating something about how this works. I'm asking for help and getting condescension. Thanks alot. – Ken Ingram Mar 22 '19 at 20:54
  • 1
    It's not my intention to be condescending, sorry. I really don't know how else to explain why your code doesn't work. Lets look at a simpler example: `function foo() { function bar() { return "baz"; }; bar(); }; var some_data = foo();`. What do you think the value of `some_data` is? It's `undefined` because `foo` doesn't contain a `return` statement. This is the same case with your `getData` function: It doesn't have a `return` statement. And adding one wouldn't solve the issue since `onreadystatechange` is called **after** `getData` has returned. – Felix Kling Mar 22 '19 at 21:00
  • `return`ing is always synchronous, i.e. it will always happen **before** any *asynchronous* process that the function triggered is done. – Felix Kling Mar 22 '19 at 21:01
  • The only thing you can do is put `stored_data = data;` inside the callback. While this will set the value, it won't happen until the callback was executed, so you don't know when you can access the value outside of the callback. – Felix Kling Mar 22 '19 at 21:03
  • Ok. So then I need to use a Promise? My issue with the dupe is that I want to stay with Vanilla JS for the time being, and the references using jQuery are adding a coimplexity in the question that is not helping me understand how to get what I need. – Ken Ingram Mar 22 '19 at 21:05
  • As well, I understand generally that the async nature of AJAX means a return isn't going to work. It's going to execute before the asynchronous portion is complete. All I want is to have the results of the AJAX call to land in the variable. The way to do that isn't clear, and most explanations are not addressing that question in a simple way. – Ken Ingram Mar 22 '19 at 21:07
  • Your explanation of why the function ends up undefined gave me some new knowledge, so thanks for that. – Ken Ingram Mar 22 '19 at 21:09
  • How difficult is this without a Promise? – Ken Ingram Mar 22 '19 at 21:10
  • The use of jQuery is in the dupe is just an example for a an async process. The solution is the same. You don't necessarily need to use promises. Using a callback is fine. But the code that needs access to `data` has to be inside or called from that callback. I.e. `getData(function(data) { /* all code that needs data goes here */ })`. That's what the ’’Let functions accept callbacks" in the dupe explains. – Felix Kling Mar 22 '19 at 21:11
  • I know this is simple. And still, it's frying my brain. – Ken Ingram Mar 22 '19 at 21:15
  • data just needs to land in an object variable where it will be pooled with other object variables.. – Ken Ingram Mar 22 '19 at 21:16
  • Maybe provide a better example for the problem you really have? – Felix Kling Mar 22 '19 at 21:20
  • A reasonable suggestion. Although, what I wrote is all I'm attempting to do. Call a function I wrote, that grabs some data from a url, and stores the data in a variable. Am I leaving something out that makes this question confusing? I didn't think the question was very complex. I'm not sure how to ask it better. – Ken Ingram Mar 22 '19 at 21:25
  • *"So, with that understanding, If I call my getData function and assign it to a variable The data should land in that container right?"* Yes, but `getData` doesn't return anything, as I have mentioned already, so assigning the return value isn't useful. As far the assignment is concerned, your code is the same as `function getData() {}; var stored_data = getData();` *"How is it that I can have my variable resolve to the retrieved result from an async call, using VANILLA JS and a callback?"* By putting `stored_data = data;` inside the callback. – Felix Kling Mar 22 '19 at 22:02
  • if stored_data = getData(a, b), how is it that I am able to assign stored_data = data? Are you suggesting I simply call getData() and do the assignment of value from within? I'm doing the variable assignment incorrectly? – Ken Ingram Mar 23 '19 at 01:09

0 Answers0