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!

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 Creating a Basic Template Engine in Node.js Reading from Files

Where does the 'profileEmitter' var come from in the profile.js file?

hi Andrew Chalkley, et al.,

In this Building a Simple Dynamic Site with Node.JS course, on the "Reading from Files" section, I notice the profile.js file has a var on line 14,

profileEmitter = this;

...however, I don't see where this var is initially instantiated and declared elsewhere in profile.js or any of the other *.js files in the project. where does profileEmitter come from, please?

best,

ā€” faddah

 portland, oregon, u.s.a.

2 Answers

akak
akak
29,445 Points

Hi Faddah,

To understand that you must recall basic JS prototypical inheritance rules plus have some knowledge how EventEmitter in node.js works. It's quite extensive topic - I don't know how much you know about it and I'm not the best teacher in the world but let me try to just shed some light.

In profile.js Andrew created a function Profile from which he can create object instances. (object oriented programming). In JS there are no classes like in other languages - there are prototypes, that can be inherited and by doing that you get access to properties of other object prototype.

EventEmitter is also this kind of function - you can do var emitter = "new EventEmitter" and get object that inherits from EventEmitter prototype. So you can call all methods on it like emitter.emit('something') etc.

Now the cool part is that you can inherit EventEmitter prototype in your own functions. This is used heavily in node.js. Even internal node.js stuff like 'http' or 'fs' inherits from EventEmitter.

Andrew is also doing this. Near the end of file he extends his Profile prototype by EventEmitter prototype by doing util.inherits(Profile, EventEmitter).

On the first line of Profile function there is a line EventEmitter.call(this). At this point Andrew takes the prototype of EventEmitter and makes it accessible in Profile function. So now his Profile function can emit and listen to events!

Back to the original question - by doing 'profileEmitter = this' (this would not work in strict mode, he should use var profileEmitter) he binds current context of 'this' to a variable that can be used inside other functions (just like the 'var self = this trick').

Daniel Emery
Daniel Emery
6,772 Points

Hi akak,

Can you explain WHY Andrew is using the Profile constructor and creating new instances of it for this task?

Why not just execute the http request to treehouse directly every time a user searches for a user name?

Thanks in advance for the help.

-Dan

akak
akak
29,445 Points

The whole 'get profile from treehouse' logic is in separate module. And inside of it he uses http requests either way - the thing that is different from like 'basic' way of doing it is the way he handles callbacks. I can think of three conventions here. Normal callbacks, EventEmitter or promises. With his new Profile constructor function that inherits from EventEmitter he has to create object instance that can listen and emit events. You can find more about event emitter in node.js documentation. But to just show the difference, here is part of Andrew's code:

//get json from Treehouse
    var studentProfile = new Profile(username);
    studentProfile.on("end", function(profileJSON){
      //show profileJSON
    });  
    studentProfile.on("error", function(error){
      //show error
    });

  }

but it could be rewritten to plain old callbacks.

var profile = require("./profile.js");

// just a function instead of object constructor - have in mind that profile.js would have to be rewritten as well
// to support normal callbacks - since that's quite some code I won't rewrite that.

profile(username, function(error, profileJSON) {
        if (!error) {
            //show profileJSON 
        } else {
            // show error
        }
 }); 

Hope that helps :) I would recommend reading about EventEmitter or looking for some tutorial online. When you get how it works Andrew's code will get way more understandable. (and in fact EventEmitter basics are not that complicated).

Cheers!

Daniel Emery
Daniel Emery
6,772 Points

Ok cool. That was the conclusion I came to. I was busting my brain trying to figure out why he did it that way, then I just realized it's ONE way to do it, and is a good example of modularization (and using emitters).

Thanks!