JavaScript Node.js Basics Handling Errors in Node Handling Parsing Errors with try and catch

Michael Williams
PRO
Michael Williams
Pro Student 8,057 Points

Why don't I need to give my printError function a parameter?

Andrew really whizzed right through the last bit of this video. We changed out all of the console.errors with our printError function defined at the top, including arguments. However, on line 40 (I've commented it out and pointing to it with a big arrow to make it obvious which line at the bottom), we didn't give it an argument like we did the others. So I'm a little confused as why.

// Problem: We need a simple way to look at a user's badge count and JavaScript points
// Solution: Use Node.js to connect to Treehouse's API to get profile information to print out

//Require https module
const https = require('https');

// Print Error Messages
function printError(error) {
  console.error(error.message);
}

//Function to print message to console
function printMessage(username, badgeCount, points) {
  const message = `${username} has ${badgeCount} total badge(s) and ${points} points in JavaScript`;
  console.log(message);
}

function getProfile(username) {
  try {
    // Connect to the API URL (https://teamtreehouse.com/username.json)
    const request = https.get(`https://teamtreehouse.com/${username}.json`, response => {
                            let body = "";
                            // Read the data
                            response.on('data', data => {
                              body += data.toString();
                            });

                            response.on('end', () => {
                              try {
                                // Parse the data
                                const profile = JSON.parse(body);                            
                                // Print the data
                                printMessage(username, profile.badges.length, profile.points.JavaScript);
                              } catch (error) {
                                printError(error);
                              }
                            });

                          });
//    request.on('error', error => printError);         <---------------------This is what I'm talking about 
  } catch (error) {
    printError(error);
  }
}

const users = process.argv.slice(2);
users.forEach(getProfile);

6 Answers

Dario Bahena
Dario Bahena
10,685 Points

It is a mistake. It should be:

request.on('error', error => printError(error));
// or this works too because the argument is 
// passed automatically to the printError function and run
request.on('error', printError);

Simpler example:

function print(data) {
  console.log(data);
}
const foo = [1, 2, 3, 4];

foo.forEach( x => print); // this will not execute and just return undefined
foo.forEach( x => print(x)); // this will print correctly
yoav green
yoav green
8,611 Points

why the argument is passed automatically?

Jazz Jones
Jazz Jones
8,533 Points

I haven't taken this course yet, or really did anything with Node.js that didn't have the express framework, but from glancing at it that line of code I think it'll just print undefined in the console, because you're not passing it the error object. Plus it seems pointless to have an on error function with the request object, as you already have the try catch block collecting any and all errors. I'd think it'd be safe just to remove that line.

Michael Williams
Michael Williams
Pro Student 8,057 Points

Yeah, I'm a little confused by it as well, as to why we need it. I'm wondering if it was just to show us how to do it.

Maybe I'm just having a dense moment, but I don't see how it will print the error if you're not passing an argument which it says that it needs to run the function.

Michael Williams
PRO
Michael Williams
Pro Student 8,057 Points

Thank you, Dario Bahena. The weird thing is that my program still ran. So I'm stumped.

Dario Bahena
Dario Bahena
10,685 Points

Your program will still work because that piece of code will only run if there is an error that happens on a request. If there are no requests with errors, that function will never run. Further more, if there was an error on a request what will run is just a function that returns a function because the printError function is not actually being called/invoked.

So in the example I gave foo.forEach(x=> print)

This is syntactically correct although logically not. This is why your program still runs.

Michael Williams
PRO
Michael Williams
Pro Student 8,057 Points

yoav green Can you explain? I don't fully understand your question.

Dario Bahena
Dario Bahena
10,685 Points

@yoav green

This is what is happening under the hood. In essence, the print function is given as a parameter. The anything function then runs it if its condition is met. In JavaScript, functions can be passed as regular arguments. In other words, just because it is a function, does not mean it has to be invoked directly.

In the anything function, fn is a variable that references whatever value you pass it. The way this function is written, when you give fn the value of a function, it will call it as a function.

function print(data) {
  console.log(data);
}
function anything(condition, fn) {
  const str = "some string";
  if (condition) fn(str);
}


anything(true, print);
anything(true, whatever => print(whatever));