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 Build a Simple Dynamic Site with Node.js Handling Routes in Node.js Populating User Information

Why does the node.js course not explain how the profile information is retrieved through the profile.js file?

That seems to me like a very important piece of the application. The profile.js file is written already and no walk through is offered.

Hi Wayne,

It's been a while since I've done this course so I don't remember exactly what was covered but we can still have a look at the file (profile.js) in the workspace your question is tied to and we get this:

var EventEmitter = require("events").EventEmitter;
var http = require("http");
var util = require("util");

/**
 * An EventEmitter to get a Treehouse students profile.
 * @param username
 * @constructor
 */
function Profile(username) {

    EventEmitter.call(this);

    profileEmitter = this;

    //Connect to the API URL (https://teamtreehouse.com/username.json)
    var request = http.get("http://teamtreehouse.com/" + username + ".json", function(response) {
        var body = "";

        if (response.statusCode !== 200) {
            request.abort();
            //Status Code Error
            profileEmitter.emit("error", new Error("There was an error getting the profile for " + username + ". (" + http.STATUS_CODES[response.statusCode] + ")"));
        }

        //Read the data
        response.on('data', function (chunk) {
            body += chunk;
            profileEmitter.emit("data", chunk);
        });

        response.on('end', function () {
            if(response.statusCode === 200) {
                try {
                    //Parse the data
                    var profile = JSON.parse(body);
                    profileEmitter.emit("end", profile);
                } catch (error) {
                    profileEmitter.emit("error", error);
                }
            }
        }).on("error", function(error){
            profileEmitter.emit("error", error);
        });
    });
}

util.inherits( Profile, EventEmitter );

module.exports = Profile;

Inside the profile function we can see exactly how this file is used. The comments are also helpful in understand what is going on.

Node takes advantage of the asynchronous nature of javascript by using request object and response object pairs. The program sends and request and moves directly on to the next piece of executable code. When the response object is returned the code that is tied to it is triggered. (Sorry if this is all review for you).

So basically what we have done is created an EventEmitter object that is called once for each username. A request is sent to the treehouse API asking for the json object related to username. First the error is handled, then the response data chunks are strung together inside body. When the end of the response is reached the data we asked for is stored in the profile variable. This is then returned to whichever file is calling it (which I believe is example_profile.js in this case).

When I was first figuring out this stuff I found it helpful to send requests to the API in the browser and to look through the response object. I hope this helps.

7 Answers

kushalmahajan2
kushalmahajan2
7,683 Points

This is exactly what I was going to post as a question but saw this question present already. Why would the basic purpose of the course be defeated by not explaining profile.js amendments. I call it amendments because some code of getting the profile info is similar but there is a lot more going on. This has happened before too with some course of Andrew that he will make the changes in the background and spoon feed us with his code. I am sorry but such a thing is not acceptable. All are here to learn after all.

Seeing the first answer of pasting in the profile.js code is like searching the node.js documentation ourselves and try to fill in the gaps. Isn't why we seek teacher's help at treehouse ? I can have best of the references and solve it. But time is a big factor in our lives esp for the people who work. I feel so pathetic to look at this query posted 7 months before to only see that this request has just went unnoticed or maybe not paid heed, if noticed. Better not to run a course like this and put up online. We can always get an updated reference from the documentation and better replied forums if the purpose is to just learn some functions in the face of building a project.

Could you explain what is the meaning of these two lines?

EventEmitter.call(this);

profileEmitter = this;

Also thanks for explaining the profile.js file. Although I am hoping someone could also explain why the profile.js file is not explained in the course itself.

EventEmitter is a core library in node that allows us to make our own event emitters. This is done by inheriting. Profile is a constructor function and in the line EventEmitter.call(this) allows the created object to inherit EventEmitter making it an event emitter (pretty cool trick).

this is a property of a function on execution. this is a variable with the value of the object that invokes the function where it is used. The this reference ALWAYS refers to (and holds the value of) an object—a singular object—and it is usually found inside a function or a method.

I hope this helps. These concepts are definitely tricky.

in the line profileEmitter = this;

what is "profileEmitter"? why isnt it declared like var profileEmitter ...

Maciej Sitko
Maciej Sitko
16,164 Points

Using call(this) as shown is a pattern called mixin, it basisally mixes in eventEmitter object in the Profile function so it can use its functions natively which is, in turn, done by referencing to its inner environment by 'this'. 'this' is captured in a variable to capture this reference and prevent it from losing binding.

But at this point 'this' could simply points to global scope... Why?

The default binding for 'this' is global scope and it has no way to look-up scopes as variables do.

But what really binds them and makes parent class (eventEmitter) available to be used in a way super-class are used in true OOP languages, is util.inherits. It i really similar (i guess so) to linking prototypes between "instances".

In JavaScript if we want a variable to have a global scope, then we don't include var before the variable name. If you include it then also it's the same given the variable is declared well above the working code.

Patrizia Lutz
Patrizia Lutz
1,449 Points

Some of the code is explained in the Node.js Basics course: https://teamtreehouse.com/library/nodejs-basics/

profileEmitter is a variable. I'm not sure why it isn't declared properly. You can play around with the code inside workspaces and see is adding var changes anything. Sorry I can't be more helpful.

Hi there, I'd like to highlight that I've just stucked on this:

  var studentProfile = new Profile(username);
  studentProfile.on("end", function(profileJSON){

Where did it come from function(profileJSON) and new Profile(username) ? I can't find those piece of code in profile.js. or anywhere in files attached to the course.

Please for youe help. Thank you in advance.

Andrew Chalkley
STAFF
Andrew Chalkley
Treehouse Guest Teacher

Hey there,

The code in the profile.js file isn't explained in the course because it would be too much of a distraction for "Building a Dynamic Site with Node.js". Think of it as a 3rd party library or a black box where only the interface (the external API) is exposed to you. If you notice it's got a similar interface to the http client for retrieving data, so I wanted there to be some familiarity with it's API for asynchronous data calls.

The util object is a helper object in Node.js. The inherits method extends the behavior of a Type with another Type. In our case it's the Profile object wanting to inherit or have behavior of EventEmitter.

EventEmitter allows you to programmatically create events of your own and provide ways to have handlers. Here's a simple example without all the network code. It's a Race Type that when it starts and finished it emits events started and finished. These could be named anything but I've decided started and finished are sensible. Later in the script I initialize a race instance and start the race. The race finishes 1000 milliseconds later or 1 second.

var EventEmitter = require("events").EventEmitter;
var util = require("util");

/** Race Constructor function */
function Race() {

}

Race.prototype.start = function() {
    /** Emits the start time on the "started" event */
    this.emit("started", new Date());
}

Race.prototype.finish = function() {
    /** Once the race is over emit the finish time on the "finished" event */
    this.emit("finished", new Date());
}

util.inherits( Race, EventEmitter );

/** Using the Race (which is an EventEmitter) */

var race = new Race();

race.on("started", function(startTime){
   console.log(startTime) 
});
race.on("finished", function(endTime){
   console.log(endTime) 
});

race.start();
setTimeout(function() {
    race.finish();
}, 1000);

The output is:

Mon May 23 2016 09:19:19 GMT-0700 (PDT)
Mon May 23 2016 09:19:20 GMT-0700 (PDT)

We need to cover the more advanced concepts of Node like EventEmitter, streams and the utils in a course or workshop.

A side note profileEmitter = this; should be var profileEmitter = this;. I used a variable because of the scoping issues with the response callbacks. I'll update the code in the workspace for new students.

Hope that clarifies it.

Thank you for your response. It definitely cleared up some of my questions. There is something I still don't understand though. Why do we need to use event emitter pattern at all. Couldnt we just call the treehouse API (https://teamtreehouse.com/username.json) directly from the main program without creating an event object?

Andrew Chalkley
Andrew Chalkley
Treehouse Guest Teacher

It was to simplify the code, and not get too distracted from the server request/response cycle and the other request/response of the API client.