The way that node.js works is that it register events and enters an infinite event loop. Events are then handled in a non-blocking manner by executing the callbacks associated to each event.

Introduction to Node.js

Events

As we saw in the previous example, many objects in Node emit events (for instance, the net.Server object emits the request event to handle HTTP requests). Objects in Node inherit this functionality from the EventEmitter class as illustrated in the example below:

// example of an emittervar EventEmitter =require('events').EventEmitter
var logger =newEventEmitter()// create a listener for the error event// we can add as many listeners as we want
logger.on('error',function(message){
console.log('ERROR: '+ message)})// trigger the error event
logger.emit('error','Exposion!!!')

This event mechanism is in the core of Node.js.

Streams

Streams lets us process information that is transferred over the wire as soon as it gets to our server. They can be readable, writeable or both.

You can read information from Readable Stream (also an EventEmitter) by listening to its data and end events as in:

Because handling streams in node.js is non-blocking, we can easily create a file uploader with a progress bar with the source code below:

http
.createServer(function(request, response){var newFile = fs.CreateWriteStream('file.txt')var fileBytes = request.headers['content-length']var uploadedBytes =0// this directly writes file being uploaded// into a file within the server
request.pipe(newFile)// but we also want to add a listener// for the data event so we can report the progress// back to the client
request.on('data',function(chunk){
uploadedBytes += chunk.length
var progress = uploadedBytes / fileBytes *100
response.write('progress: '+parseInt(progress,10)+'%\n')})
request.end()}).listen(8080)

Require Search

default: require(httpclient)(it looks by default in the nodemodules directory, either at the current path or parent folders)_

NPM: The Node Package Manager

NPM comes with Node.js and it lets you easily install third party modules in your application. It manages dependencies between modules so that when you install a module, it automatically grabs all dependencies.

# Installs into local node_modules directoryPS> npm install <name_of_the_library>
# Install module globallyPS> npm install <name_of_the_library> -g
# Note that global npm modules cannot be required# They are usually used more as utilities, like coffeeScript# If you want to require them as usual, you need to install them locally as wellPS> npm install coffee-script -g # install globalPS> npm install coffee-script # install local

# Seach modulesPS> npm search <search_term>

Defining your Application Dependencies

For big applications that depend on lots of npm modules, you can define a package.json file in your application root that contains metadata for your application (like for example its dependencies to other modules):

When we define this file, we can execute npm install and npm will go and install all our dependencies in the node_modules folder. The dependencies of your dependencies will be installed in a nested fashion so as to avoid naming conflicts.

var express =require("express");var socket =require("socket.io");var app = express.createServer();// listen with socket.io for connectionsvar io = socket.listen(app);
io.sockets.on("connection"),function(client){
console.log("Client connected...");// once the client has connected, we can send messages to it
client.emit("messages",{message:"Hello client!"});});// we also set up an event to receive messages from the client
client.on("messages",function(data){// data comes within a message from the client
console.log(data);// hello server!});}

Socket.io also makes it very easy to broadcast messages to all clients, by using client.broadcast.emit("messages", data).

Socket.io also provides support for saving data associated to a given socket. For instance, we could save a nickname associated to a given client by:

io.sockets.on('connection'),function(client){
client.on('join',function(name){// join is a custom event// save nickname on the socket
client.set('nickname', name)})
client.on('messages',function(data){
client.get('nickname',function(err, name){// get the nickname and use it when broadcasting
client.broadcast.emit('chat', name +': '+ message)})})}

Would you like to receive more articles like this one on programming, web development, JavaScript, Angular, developer productivity, tools, UX and even exclusive content like free versions of my books in your mailbox? Then sign up to my super duper awesome inner circle.

Did Ya Know I've Written Some Books?

I have! The JavaScript-mancy series is the lovechild of three of my passions: JavaScript, writing and Fantasy. In the pages of each one of the books of the series you’ll find a breadth of JavaScript knowledge, delivered with a humorous and casual style of writing and sprinkled with Fantasy at every turn.

They are the weirdest and quirkiest JavaScript books you'll ever find. There's nothing out there quite like it.