3

So I've been following these posts: here, and here etc.

But I'm still getting 'undefined' as an output, and it's appearing instantly, so I don't think it's waiting for the callback.

I've been trying to solve this for so long. I just don't understand it. I believe that I understand the concept of callbacks, but in practice, I'm not understanding the syntax of all these functions. I've followed the posts almost exactly, the only difference is how I'm using the buttonClick. I would really appreciate some help on getting this working. I've simplified my code which is on CodePen here and also below.

Can anyone direct me please?

<button onclick="buttonClick()">Click Me</button>
<span id="output"></span>

<script
  src="https://code.jquery.com/jquery-3.5.1.min.js"
  integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
  crossorigin="anonymous"></script>

<script type="text/javascript">

function buttonClick() {
    document.getElementById('output').innerHTML=getHTML(myCallback);
}

function getHTML(callback){
    $.ajax({
        url: 'https://cors-anywhere.herokuapp.com/https://www.google.com/',

        success: callback
    })
}
    
function myCallback(result){
    console.log(result.slice(0,100))
    return result.slice(0,100)
}
  • All in here: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call?rq=1 – user2864740 Jan 12 '21 at 00:33
  • 1
    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) – user2864740 Jan 12 '21 at 00:34
  • I havent used jQuery in forever, but 'success' callbacks have been replaced a while ago. You may have to use the .then() notation instead. Like `$.ajax(url).then(function(result) { ... }, function(error) { ... });` – oooyaya Jan 12 '21 at 00:35
  • 1. Your `getHTML` function doesn't return anything. 2. `return result.slice(0,100)` inside `myCallback` is discarded –  Jan 12 '21 at 00:45
  • @user2864740 That post is one of the two in the question. It's how I got this far. – Alfie Stoppani Jan 12 '21 at 00:47
  • Here's the quick fix: https://jsfiddle.net/2uqowbLk/ –  Jan 12 '21 at 00:48
  • 1
    @AlfieStoppani Hmm, the answers should have been helpful. Remember that asynchronous in JavaScript **always** requires waiting on the **_execution_** of some callback. Promises (and by extension await/async) hide this, and yet internally work on the exact same principals: the supplied callback is invoked when the result is available, and there is no available result until such a time as it is invoked. – user2864740 Jan 12 '21 at 02:10

2 Answers2

1

Your problem is that getHTML() does not block. It returns undefined immediate, not waiting for the result of the function. You can use the follow asyncrhonous pattern to solve your issue. I suggest you review async code on MDN.

async function buttonClick() {
  const html = await getHTML(myCallback);
  document.getElementById('output').innerHTML = html;
}

async function getHTML(callback) {
  const result = await $.ajax({
    url: 'https://cors-anywhere.herokuapp.com/https://www.google.com/'
  });
  return callback(result);
}

You could alternatively use promises, but it'd be a bit harder to read. I don't recommend callbacks here (myCallback in the above code is unnecessary even if it does work).

ChiralMichael
  • 1,214
  • 9
  • 20
1
<button onclick="buttonClick()">Click Me</button>
<span id="output"></span>

<script
  src="https://code.jquery.com/jquery-3.5.1.min.js"
  integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
  crossorigin="anonymous"></script>

<script type="text/javascript">
function getHTML(callback,err){
    $.ajax({
        url: 'https://cors-anywhere.herokuapp.com/https://www.google.com/',
        error: err,
        success: callback
    })
}

function buttonClick() {
    getHTML(function(data){
        document.getElementById('output').innerHTML=data;
    }, function(xhr,status,err){
        document.getElementById('output').innerHTML='SERVER ERROR!';
        console.log(err+', status:'+status)
    });
}
</script>

you were instantly setting the output element to the return of your call - you need to wait for the data to be ready INSIDE the callback.

Dan
  • 3,755
  • 4
  • 27
  • 38
  • I have one more question @Dan please. If I want it to return "#server error" on error. I can't just put ```error: "#server error"``` can I, because that won't callback. Error would need to be a function wouldn't it? But how to I get that to callback. I'm so confused with this syntax. I know I'll understand this once I've seen it demonstrated and I can play around with it, but at the moment, I'm so confused. This is what I was trying last https://codepen.io/alf-the-elf/pen/eYdPWmM. – Alfie Stoppani Jan 12 '21 at 16:52
  • 1
    sure, i edited my answer to include an error callback. So notice how the err parameter in getHTML is second? If you respect that in the click function and include a second function to act as your err callback, you can get more pertinent data. I saw on the jquery documentation for $.ajax that they include 3 parameters for you to use, xhr, status, and error. You can do what you wish with those. – Dan Jan 12 '21 at 19:59