-2

I am trying to return a value from an asynchronous function call, and I understand, from posts such as this that you can't use a return. However, it is implied that I should be able to accomplish this with proper use of callbacks and promises. Unfortunately, I am having a difficult time to figuring out exactly how to handle the problem I have below.

Here, I want to return a URL value that I'm obtaining from an AJAX call.

 function getGithubURL(name){
  var ghUserURL = 'https://api.github.com/users/bullcitydave?client_id=-----&client_secret=------';

  var jsPromise = Promise.resolve($.getJSON(ghUserURL));

  var avatar;

  jsPromise.then(function(data) {
      avatar = data.avatar_url;
      console.log(avatar);  // I have the correct value here
    });

  return avatar; // how do I return it correctly?
};
Community
  • 1
  • 1
bullcitydave
  • 925
  • 1
  • 8
  • 19
  • you can't do that... the only solution is to use a callback method to handle the value returned from the promise – Arun P Johny Jul 31 '14 at 03:46
  • You can "return" it by passing a callback function to your `getGithubURL` function, calling that inside the `jsPromise.then` (and passing it the `data.avatar_url`, and inside that callback running `console.log('The URL for my Github image is',x);` – Ian Jul 31 '14 at 03:47
  • http://jsfiddle.net/arunpjohny/sXu3r/1/ – Arun P Johny Jul 31 '14 at 03:49
  • 1
    @benjamin-gruenbaum - do you really want to mark this as a dup of that question? The crux of this question is really how to use promises to get a piece of an ajax result out of his function. The question you marked this a dup of deals with the async problem he has, but offers zero help with how to use promises to solve the issue (see my answer where I attempted to address that). I decided to vote to reopen. The question you marked it a dup of only addresses one part of this question and not the more interesting part in my opinion. – jfriend00 Jul 31 '14 at 04:31
  • I think the first paragraph strongly implies that OP's big issue here is how to return from an asynchronous function and that using promises is just an approach OP has tried - " with proper use of callbacks and promises.". Having a promises answer on _that_ question and explaining how to use them to handle returns of async values might be useful on the other hand. – Benjamin Gruenbaum Jul 31 '14 at 04:34
  • Thanks Arun and I for the examples. However, I need to go back and clarify my question. I am needing to return this avatar URL value to a process I don't have control over. The first line and last night were meant to make for a simple example. – bullcitydave Jul 31 '14 at 04:49
  • I should clarify my question. I am needing to return this avatar URL value to a process I don't have control over. The var x and console.log lines are besides the point. I was trying to indicate that I need to call a single function that returns the value I need. I don't care if that single function has several chained functions within it. As far as this question being marked a dup of another, I wish you would not do that. I am posting this specific question because "similar" questions haven't helped me, and I need a specific answer. @jfriend00 thanks you for voting to reopen. – bullcitydave Jul 31 '14 at 04:59
  • 1
    @bullcitydave - You can't just return the value synchronously. You will have to return it via a callback function or a promise (which is really just a callback too, but in a helpful structure). I agree with Benjamin that if you're still trying to return an async value from a synchronous function, then you should read http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call because that is NOT something that javascript can do. An alternative would be to force the async ajax call to be synchronous, but that is generally a bad design decision. – jfriend00 Jul 31 '14 at 05:05
  • Have you read http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call ? You should really consider reading it. – Benjamin Gruenbaum Jul 31 '14 at 05:05

1 Answers1

1

You can't return a value in your synchronous function that was acquired from an asynchronous operation. The async operation won't complete until sometime later so it simply isn't available yet when your getGithubURL() function returns. It's a matter of timing and just something that javascript can't do.

You can solve your problem by restructuring how you use promises. What you want to do is to make a .then() handler be the consumer of the final data. That way you can pass the data back through your promise structure. You also want to make use of the promise that $.getJSON() already returns - no need to create your own promise here.

Here's one way to do that.

getGithubURL("bullcitydave").then(function(url) {
    // you can use the avatar url here
});

function getGithubURL(name){
  var ghUserURL = 'https://api.github.com/users/bullcitydave?client_id=-----&client_secret=------';

  return $.getJSON(ghUserURL).then(function(data) {
      return data.avatar_url;
  });
};

You call $.getJSON(). It returns a promise which you add a .then() handler on in order to extract the actual data you want. From the .then() handler, you return the final data you want. The $.getJSON().then() sequence creates a new promise which is what you return from your getGithubURL() function and is not resolved until the getJSON().then() sequence is done. That will present your avatar URL to the outer .then() handler as shown in the code above.


Or, if the caller of your getGithubURL() function isn't going to use promises, then you can make your function take a callback like this:

getGithubURL("bullcitydave", function(url) {
    // you can use the avatar url here
});

function getGithubURL(name, fn) {
  var ghUserURL = 'https://api.github.com/users/bullcitydave?client_id=-----&client_secret=------';

  $.getJSON(ghUserURL).then(function(data) {
      // call the callback and pass it the avatar url
      fn(data.avatar_url);
  });
};
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • @bullcitydave - Added a plain callback option for `getGithubURL()`. – jfriend00 Jul 31 '14 at 05:11
  • thank you for your time and the responses are giving me valuable understanding. This is a difficult problem for me to explain. It seems like no matter what route I go, I am left with a return value corresponding to a secondary function all. What I really have a primary function wrapping all of this up, and the primary function needs to report the result. So, if looking at your last code snippet, imagine a basic higher-up function within which nests all of your code How can I have that code return data.avatar_url? Does what I am asking make sense? I truly appeciate this feedback and... – bullcitydave Jul 31 '14 at 05:35
  • Thank you @jfriend00, I don't doubt you and I am grateful for the feedback. Best regards! – bullcitydave Jul 31 '14 at 05:44