1

I'm relatively new to JS, and have been stuck on this problem for a while. I am trying to assign a variable from the return value of a function, like this:

var data = makeApiRequest(url);

However, the code continues before the makeApiRequest() function completes, causing data to be undefined.

I've been researching the problem for a while and found that the problem can be fixed with a callback. My issue is I'm not sure how to get data assigned to the result of makeApiRequest() in doing so.

I found this example (on callbackhell.com) that I think perfectly illustrates my problem:

var photo = downloadPhoto('http://coolcats.com/cat.gif')
// photo is 'undefined'!

Author's solution:

downloadPhoto('http://coolcats.com/cat.gif', handlePhoto)

function handlePhoto (error, photo) {
  if (error) console.error('Download error!', error)
  else console.log('Download finished', photo)
}

console.log('Download started')

The thing that I cannot figure out for the life of me is how photo is assigned (or even declared) in this example. I feel like if I could crack that, I could figure out my specific problem. Any help would be greatly appreciated. Thanks very much in advance.

Curtis
  • 19
  • 2
  • 1
    Possible duplicate https://stackoverflow.com/a/14220323/660884 – Volem Jul 27 '17 at 20:01
  • My bad, even though I searched I still posted a dup! "Asynchronous" was probably the word I was missing in my searches. But thank you all for the responses. Matthewninja's solution worked great for me, but I'll definitely be studying up on Promises. Sorry again for the dup question! – Curtis Jul 27 '17 at 23:29

3 Answers3

2

makeApiRequest(url) is an asynchronous call. That means that if you try to evaluate it immediately after calling it, it will be undefined. The modern solution is to use a Promise.

However, a callback function is perfectly acceptable if your logic won't go layers deep. You can do so by altering the parameters on your makeApiRequest function like so:

function makeApiRequest (url, callback) {
    // make the api call, and then:
    callback(results);
}

Now, you will call makeApiRequest() as such:

makeApiRequest (url, function(data) {
    // handle your data here.
    console.log(data);
});
matthewninja
  • 360
  • 5
  • 21
0

When download function completes, it invokes callback function handlePhoto with data (photo) passed to it as a second argument, so that it can be used inside of the handlePhoto function.

marzelin
  • 10,790
  • 2
  • 30
  • 49
0

If you want to assign the return value of a promise then you could wrap the variable inside async function and later use await.

** But async and await is a new feature and not widely supported.

So in your case assuming makeApiRequest() returns a promise

  async function any(){ /* using async before function declartion*/

    var getValue = await makeApiRequest(); // using await 

    console.log(getValue); // returned value of makeApiRequest 
  }
error404
  • 331
  • 1
  • 8