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 Node.js Basics (2014) Building a Command Line Application Perfecting: Getting Multiple Profiles

Nikolay Komolov
Nikolay Komolov
23,033 Points

What causes 'TypeError: listener must be a function' after editing an error message?

Hello everybody! Could you help me, please?

After editing this line:

request.on("error", printer.printError({message: "Connection failed. Check connection to the Internet"}));

I get a message: 'events.js:210 throw new TypeError('listener must be a function');' , although it prints out this custom error message before.

app.js:

var profile = require("./profile.js");
var topic = process.argv[2];
var users = process.argv.slice(3);
//users.forEach(profile.get);
for(var i = 0; i < users.length; i++){
    profile.get(topic, users[i]);
}

profile.js:

// Problem: we need a simple way to look at badge count and points
// Solution: use node.js to connect to treehouse's API to get profile info
var http = require("http");
var https = require("https");
var printer = require("./printer")


function get(topic, username){
//Connect to the API URL (https://teamtreehouse.com/username.json)
    var request = https.get("https://teamtreehouse.com/" + username + ".json", function(response){
        var body = "";
        //Read the data
        response.on('data', (chunk) => {
            body += chunk;
        });


        response.on("end", () => {
            if(response.statusCode === 200) {
                try {
                    //Parse the data
                    var profile = JSON.parse(body);
                     //Print the data  
                    printer.printMessage(username, profile.badges.length, profile.points[topic], topic);
//                    console.log(topic);
                } catch(error) {
                    //parseError
                    printer.printError(error);
                }
            } else {
                //Status Code Error
                printer.printError({message: "There was an error getting the profile for " + username + ". (" +  http.STATUS_CODES[response.statusCode] + ")"});
            }
        });
    });

    //Connection Error
    request.on("error", printer.printError({message: "Connection failed. Check connection to the Internet"}));
}

module.exports.get = get;

printer.js:

// Print out message
function printMessage(username, badgeCount, points, topic) {
    var message = username + " has " + badgeCount + " total badges(s) and " + points + " points in " + topic;
    console.log(message);
}

//Print out error messages
function printError(error){
    console.error(error.message);
}

module.exports.printMessage = printMessage;
module.exports.printError = printError;

Any ideas? Thanks!

1 Answer

akak
akak
29,445 Points

When you write printer.printError(something) you are executing the function and the value is passed instead of the function itself. So the error message is right. It expects a function, but gets a string or whatever is returned from printError function. To avoid running function while inserting an argument you can use bind. It will create a new function with the parameter but won't execute it.

request.on("error", printer.printError.bind(null, ({message: "Connection failed. Check connection to the Internet"})));

Why it works inside try-catch as in video?

else { //Status Code Error printer.printError({message: "There was an error getting the profile for " + username + ". (" + http.STATUS_CODES[response.statusCode] + ")"}); }