Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Alessandro Pepe
seal-mask
.a{fill-rule:evenodd;}techdegree
Alessandro Pepe
Full Stack JavaScript Techdegree Student 24,461 Points

Node.js question regarding http.get() from an API

Hello! I'm working on my final project for my Full Stack JavaScript Techdegree, and I've run into a bit of an issue with a function using http.get(). Essentially what I'm trying to do here is return that coordinates variable for use in another function with another API call. Before I can even get to that though, this function isn't returning anything. If I replace the return coordinates; line with console.log(coordinates); it does indeed return some coordinates from the API call in the console.

The docs say that http.get() returns a ClientRequest, which seems to be (at its essence) a promise, but even so it should still return a variable shouldn't it?

So I'm clearly missing something rather basic. Could anyone help me out here?

const http = require('http');

function get() {
  // Print out error message
  function printError(error) {
      return error;
  }
  try {
    const request = http.get(`http://api.open-notify.org/iss-now.json`, response => {
      if (response.statusCode === 200) {
        let body = "";
        // Read the data
        response.on('data', chunk => {
          body += chunk;
        });
        response.on('end', () => {
          try {
              // Parse the data
              const position = JSON.parse(body);
              // Print out temp details
              let coordinates = `${position.iss_position.latitude},${position.iss_position.longitude}`;

              return coordinates;

            } catch (error) {
                // Parse Error
                printError(error);
            }
          });
      } else {
          // Status Code Error
          const statusCodeError = new Error(`There was an error getting the ISS location. (${http.STATUS_CODES[response.statusCode]})`);
          printError(statusCodeError);
      }
    });
    request.on("error", printError);
  } catch (error) {
      //Malformed URL Error
      printError(error);
  }

}

get();
Antti Lylander
Antti Lylander
9,686 Points

I'm interested too. Just spent 30 minutes with your code and could not get it to return anything.

3 Answers

Steven Parker
Steven Parker
230,274 Points

What are you expecting to "return" a value to? That function is called by the "end" event listener which doesn't expect or use a return value.

If you want to use the coordinates in another function, you should call that function and pass it as a parameter (as you did with console.log) instead of returning the value.

Alessandro Pepe
seal-mask
.a{fill-rule:evenodd;}techdegree
Alessandro Pepe
Full Stack JavaScript Techdegree Student 24,461 Points

Ohhhh so where that return coordinates; line is I'd have to use something like someOtherFunction(coordinates)?

Just tried it, that worked. Thanks so much!

Antti Lylander
Antti Lylander
9,686 Points

Here I have made coordinates global so that it can be accessed outside response.on 'end' callback. I've started learning node.js this week and this was pretty eye-opening. Run this and see in what order the console.logs get called. There are four of them.

const http = require('http');
let coordinates = "not yet assigned";

function get() {

  // Print out error message
  function printError(error) {
      return error;
  }

  try {
    const request = http.get(`http://api.open-notify.org/iss-now.json`, response => {
      if (response.statusCode === 200) {

        let body = "";
        // Read the data
        response.setEncoding('utf8');
        response.on('data', chunk => {
          body += chunk;
        });

        response.on('end', () => {
          try {
              // Parse the data
              const position = JSON.parse(body);
              // Print out temp details
              coordinates = `${position.iss_position.latitude},${position.iss_position.longitude}`;
             console.log(coordinates,'- called inside response on end-', new Date);


          } catch (error) {
                // Parse Error
                printError(error);
          }
          });

      } else {
          // Status Code Error
          const statusCodeError = new Error(`There was an error getting the ISS location. (${http.STATUS_CODES[response.statusCode]})`);
          printError(statusCodeError);
      }
    });
    request.on("error", printError);
  } catch (error) {
      //Malformed URL Error
      printError(error);
  }
console.log(coordinates, '-called inside get()-', new Date);

}

get();
console.log(coordinates, '-called outside get()-', new Date); //run the code and you'll find that this console.log will always be called before the one that is inside response.on
setTimeout(() => {console.log(coordinates, '-called outside get() after waiting for 1 sec-', new Date)}, 1000);
Antti Lylander
Antti Lylander
9,686 Points

Yes. And if you try to pass the coordinates to another function any other way, the problem is, you don't know whether the coordinates have been assigned to the variable yet (because http.get() is ran asynchronously). I'll post some code to illustrate this when I get the children to bed. 2 hours approx.