0

I am making a call to an API within a function. At this point I get "undefined" as the returned value. I know the call to the API is successful since the URLs that I am trying to get in the call print to the term no problem. I am 99% sure that call to the encapsulating function gets triggered before the request function is done ("undefined" is returned before URLs are listed). Wanted to confirm this and ask if there is a tutorial or code snippet someone could point me to with a good description of a pattern I should follow in this case. <-- Obviously still struggling with the async nature of the beast :)

  function GetPhotoURLs(url){

  var photo_urls= new Array();

  request({
      url: url,
      json: true
  }, function (error, response, body) {


      if (!error && response.statusCode === 200)
      {
          //console.log(body) // Print the json response
          var inhale_jsonp=body;

          var blog_stream= inhale_jsonp.substring(22,inhale_jsonp.length-2); //getting JSON out of the wrapper 
          blog_stream=JSON.parse(blog_stream);

          for(var i=0;i<blog_stream.posts.length;i++)
          {
            photo_urls[i]=blog_stream['posts'][i]['photo-url-500'];
            console.log(photo_urls[i]+"\n"); //checking that I am getting all the URLs

          }

          console.log("success!");
          console.log(photo_urls[1]);
          return photo_urls;
      }
      else
      {
          photo_urls[0]='none';
          console.log("nope!");
          console.log(photo_urls[0]);
          return photo_urls;
      }

  });

}

output sequence --> 1. undefined 2. Listing of URLs 3. Success message + second element from URLs array

dima
  • 870
  • 8
  • 10

1 Answers1

1

The request() function is asynchronous. As such, it finishes long after your original function has completed. Thus, you can't return the result from it (the result isn't even known yet when the function returns). Instead, you must process the result IN your callback or call a function from within that callback and pass the result to that function.

As for general design patterns for this type of work, you can either process the result in the callback as suggested above or switch to using promises to help you manage the asynchronous nature of the request. In all cases, you will be processing the result in some sort of callback.

You can read this answer for some more detail on handling async responses. That specific answer is written for client-side ajax calls, but the concepts for handling async responses are identical.


In your specific case, you may want to make getPhotoURLs() take a callback function which you can call with the result:

function GetPhotoURLs(url, callback){

    .....

    request(..., function(error, response, body) {

        ...

        // when you have all the results
        callback(photo_urls);
    })

}

GetPhotoURLs(baseurl, function(urls) {
    // process urls here

    // other code goes here after processing the urls
});
Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • @jfriend000 Thank you for showing example in context! As mentioned in my Q a bit wobbly with the async operations but I have a clear learning direction now. – dima Jan 04 '15 at 04:18