Category Archives: javascript

Getting my Mongo on

This is the sixth post in a small series on Node.js. In this post, I will take a look at how to use my MongoDB from a Node app.

First, let’s install a driver for MongoDB: node-mongodb-native:

npm install mongodb

NPM really make it easy to get going!

Now, in order to connect to MongoDB, do this:

var mongo = require('mongodb');
var server = new mongo.Server(host_name, port_number, {auto_reconnect: true});
var db = new mongo.Db(database_name, server, {});
 
db.open(function(err) {
    // if you need to authenticate, do it here (otherwise just omit the following line):
    db.authenticate(username, password, function(err) {
        // now we're ready!
    });
});

This should be done only once when the application starts up.

Then, to access a collection, do this:

db.collection(collection_name, function(err, coll) {
    // do stuff in here
});

Inside the function above, coll gives you access to do all the usual stuff to a MongoDB collection. To name a few, there’s insert, find, findOne, ensureIndex, count, etc.

As the node-mongodb-native documentation is pretty sparse, I’ve found it useful to open up a Node.js shell and connect with the driver, allowing me to inspect the various objects’ properties and methods, e.g. by inspecting db.__proto__ like so:

mogens-heller-grabes-macbook-pro:~ mhg$ node
> var util = require('util');
> var mongo = require('mongodb');
> var server = new mongo.Server('localhost', 27017, {auto_reconnect:true});
> var db = new mongo.Db('test', server, {});
> db.open(function(err){});
> console.log(util.inspect(db.__proto__, true, 1));
{ logout: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  resetErrorHistory: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  ensureIndex: { [Function] [arguments]: null, [length]: 4, [name]: '', [prototype]: [Object], [caller]: null },
  open: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  lastError: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  dropCollection: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  executeDbCommand: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  executeCommand: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  previousErrors: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  removeUser: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  collection: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  dropIndex: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  error: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  createCollection: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  command: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  indexInformation: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  [constructor]: 
   { [Function]
     [arguments]: null,
     [length]: 3,
     DEFAULT_URL: 'mongo://localhost:27017/default',
     super_: [Object],
     [name]: '',
     [prototype]: [Circular],
     [caller]: null },
  lastStatus: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  collections: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  addUser: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  cursorInfo: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  dereference: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  admin: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  createIndex: { [Function] [arguments]: null, [length]: 4, [name]: '', [prototype]: [Object], [caller]: null },
  collectionsInfo: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  collectionNames: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  dropDatabase: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  authenticate: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  renameCollection: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  close: { [Function] [arguments]: null, [length]: 0, [name]: '', [prototype]: [Object], [caller]: null },
  eval: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null } }

and coll.__proto__ like so:

> db.collection('sessions', function(err, coll) { console.log(util.inspect(coll.__proto__, true, 1)); });
{ remove: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  rename: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  save: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  insert: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  group: { [Function] [arguments]: null, [length]: 6, [name]: '', [prototype]: [Object], [caller]: null },
  ensureIndex: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  drop: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  findOne: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  checkCollectionName: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  mapReduce: { [Function] [arguments]: null, [length]: 4, [name]: '', [prototype]: [Object], [caller]: null },
  insertAll: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  createIndex: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  find: { [Function] [arguments]: null, [length]: 0, [name]: '', [prototype]: [Object], [caller]: null },
  count: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  options: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  indexInformation: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  dropIndex: { [Function] [arguments]: null, [length]: 2, [name]: '', [prototype]: [Object], [caller]: null },
  distinct: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Object], [caller]: null },
  normalizeHintField: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null },
  update: { [Function] [arguments]: null, [length]: 4, [name]: '', [prototype]: [Object], [caller]: null },
  [constructor]: { [Function] [arguments]: null, [length]: 3, [name]: '', [prototype]: [Circular], [caller]: null },
  findAndModify: { [Function] [arguments]: null, [length]: 6, [name]: '', [prototype]: [Object], [caller]: null },
  dropIndexes: { [Function] [arguments]: null, [length]: 1, [name]: '', [prototype]: [Object], [caller]: null } }

Of course this way of barfing functions all over the place is not pretty, but it makes it possible to get a glimpse of what kinds of operations that can be performed on the various objects.

What is that module thing again?

This is the fourth post in a small series on Node.js. In this post, I will take a look at how the Node.js module mechanism works.

In my previous posts on Node.js, I nonchalantly went ahead and require(...)d something called http – but what was that? And what happened when I did that?

Well, require is one of the few globals when running a Node program, and it is used to import a module. The parameter is a string, which Node uses to look for a file to load.

The simplest usage refers directly to a file relative to the path of the currently running program. E.g., if I have a module residing in a file called importantBizLogic.js in the lib folder beneath my program’s directory, I can include its exports (which I’ll get back to in a moment :) ) like so:

var biz = require('./lib/importantBizLogic');

If I omit the ./, Node will go look for importantBizLogic in each directory in the require.paths array, which is a list of default paths to search for modules.

Let’s see what it contains… Go to a terminal and enter the Node shell:

mogens-heller-grabes-macbook-pro:~ mhg$ node
> require.paths
[ '/Users/mhg/.node_modules', '/Users/mhg/.node_libraries', '/usr/local/lib/node' ]

Great – so that’ s where my global modules reside. Now, what was that export thing again?

Well, that’s related to how importantBizLogic.js is structured… in order to control how the import works, a module must explicitly export stuff – and that can be done like so:

var secretBizConstant = 0.01;
 
exports.calculateStuff = function(numbers) {
    return numbers.a + numbers.b + secretBizConstant;
};

- allowing this module to be imported and used like so:

var biz = require('./lib/importantBizLogic');
 
var result = biz.calculateStuff({a: 4.15, b: 5.42});

Nifty!

Apparently – and I am almost embarrassed that I did not know that – there is a thing called CommonJS, which is an initiative that strives to create a JavaScript standards library – and the require stuff I’ve described here is actually just Node implementating the CommonJS Modules specification. Pretty sweet, actually!

Up and running with Express

This is the third post in a small series on Node.js. In this post, I will take a look at how to get up and running with Express.

Let’s get Express installed – first, let’s install NPM – a package manager for Node:

curl http://npmjs.org/install.sh | sh

That was easy. Now, Express can installed like this:

npm install express

Too easy!

Now, let’s create a simple app like we did the last time:

cd ~
mkdir Projects/HelloExpress
cd Projects/HelloExpress
mate app.js

Punch in the following few lines:

var express = require('express');
var app = express.createServer();
 
app.get('/', function(req, res){
    res.send('Hello Express!');
});
 
app.listen(3000);

and run the app from the terminal like so:

node app.js

and navigate to http://localhost:3000 – on my machine it looked like this:
Hello Express

That was easy. See how the API pretty much resembles Node’s builtin HTTP server, except it adds routes into the mix!

Now, in order to build a web site we need some kind of view engine to help generate some HTML for us. I have used Haml a couple of years ago, and I really liked it… and luckily, some nice people have made Haml available to Node apps, so let’s try installing that:

npm install haml

Now we configure Express by punching in the following stuff in the app:

 
app.configure(function() {
	app.set('view engine', 'haml');
	app.use(express.staticProvider(__dirname + '/public'));
	app.use(express.bodyDecoder());
});

As you can see, I tell Express to use Haml as the default view engine. Moreover, I configure Express to serve static content from the /public folder in my app dir, and then I install the bodyDecoder middleware which will parse incoming posts and make posted values available in req.body.

Now, let’s alter our action to render a view:

app.get('/', function(req, res){
    var locals = {message: 'Express + Haml!!!!'};
    res.render('index', {locals: locals});
});

and now create two files, layout.haml and index.haml in the /views folder. Mine look like this – /views/layout.haml:

!!!
%html
  %head
    %title Hello Express + Haml!
  %body
    = body

and /views/index.haml:

%p
  Hello 
  = message

Now, let’s go to the terminal and node app.js and navigate to http://localhost:3000 – on my computer it looks like this:
Hello Express + Haml

As you can see, view models can be handed to the view via the locals object.

This was some basic web app stuff – only thing missing is some way to persist data, so next time I will take a look at how to get my Mongo on…

Getting started with Node.js

This is the second post in a small series on Node.js. In this post, I will take a look at how to get started and run the ubiquitous “Hello world” sample.

First, create a directory somewhere and Git clone Node… I did it like this:

cd ~
mkdir src
cd src
git clone git://github.com/ry/node.git

Then, build and install Node like this:

./configure
make
make install

If you get permission errors during the last step, you might need to do a

sudo chown -R $USER /usr/local

to grant yourself ownership of everything beneath /usr/local. Note however, that this should probably only be done if the machine is your own personal machine.

Now, try typing node -v in the terminal… I got this:

v0.3.2-pre

Now, let’s finish this post by creating a Node app like so (using TextMate or whatever you prefer):

cd ~
mkdir Projects
mkdir Projects/HelloWorld
cd Projects/HelloWorld
mate app.js

Punch in the following few lines:

var http = require('http');
 
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
 
console.log('Server running at http://127.0.0.1:8124/');

and go the terminal again and type

node app.js

which yields

Server running at http://127.0.0.1:8124/

Now, when I navigate to http://localhost:8124 I get this:

Node.js HTTP Hello World

Nifty, huh?

In the next post, I will see if I can get up and running with Express – a simple but powerful Sinatra-like web framework for Node.

I want to learn Node.js

Preface

More than three years ago, I watched a couple of videos with Douglas Crockford that changed my view on JavaScript completely!

I must admit that I too used to consider JavaScript a toy language, somehow inferior to “real programming languages” like Java and C#.

This view was of course induced by the sheer amount of JavaScript crap code available to copy/paste from the web, almost always operating on an equally crappy non-standards compliant DOM implementation in some crappy browser – but after watching those videos I actually began to understand that JavaScript was a pretty cool and powerful language.

Some time after, Crockford released JavaScript: The Good Parts which I immediately read, and at that time I remember saying to one of my colleagues: “I think it would be cool to build large systems in JavaScript”.

At that time, stuff like Rhino was around, but I had never heard of anyone actually using it, and executing JavaScript on the JVM by compiling JavaScript into Java into bytecode didn’t sound sexy at all to me.

Today

Recently, however, I have somehow come across Node.js at different occasions, and I have really been meaning to check it out. If you don’t know what Node is about, I can quote the homepage: Node is “Evented I/O for V8 JavaScript.”

That’s right! Let’s break that down:

  • Evented: There’s only one thread executing in a Node process, high throughput is achieved by doing asyncronous I/O, queueing callbacks to be executed upon completion.
  • I/O: Not usually what JavaScript is used for, but this covers the fact that Node has APIs that treat the file system and TCP and HTTP as first class citizens.
  • V8: The JavaScript is executed by the V8 JavaScript Engine that Google in Aarhus built for Chrome.

As an example, there’s the ubiquitous code sample that you’ll see everywhere – opening a HTTP server in Node:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');

As you can see, Node has a nice and thin API for working with HTTP, and as I envy Rubyists of having Rack and Sinatra, and as I am interested in how web frameworks work in general, this code sample has continued to spark my interest.

Therefore, in order to push myself through learning more about it, I have decided to see if I can write a couple of blog posts on Node.js. I will try to cover the necessary topics to develop a simple web app, and I expect to come across more or less of the following:

  • Acquiring Node.js and running a “Hello world” script. Can’t do anything without having done this.
  • Basic Node stuff, like how to structure code into files/modules/whatever and whatnot.
  • Bringing in external, possibly native libraries.
  • Building a web app, possibly with Express – a simple web framework for Node.
  • Persisting some data, probably using node-mongodb – a MongoDB driver for Node.
  • Unit testing my app – probably with the built-in assert API.
  • Hosting my app – probably with Nginx as a router and load balancer.

Wow! – that was a lot of words and almost no code… I promise that my next posts on Node will have more code in them.

How JavaScript’s closures surprised me

Well, it happened when I was making a web page on which the user could pick a number of time slots. The time slots would be configured using a calendar and a couple of time entry controls, and the user would add the time slot by clicking a button. The selected time slots would be stored as a JSON serialized array of time slots in an input element.

The selected time slots would be shown in a list on the page, each one with an X on the side which could be used to remove the appropriate time slot. The problem was, that it did not remove the appropriate time slot. But why?

It’s because of the way JavaScript’s closures are implemented!

You see, my code was something like this (using Crockford’s JSON library and the incredible jQuery):

// get array of selected time slots
var timeSlots = JSON.parse($('#selectedTimeSlotsJson').val());
 
// create representation, including a link to remove each time slot
for(var index = 0; index < timeSlots.length; index++) {
    var timeSlot = timeSlots[index];
    var id = timeSlot.id;
 
    var removeTimeSlotLink = $('<img>')
        .attr('src', deleteTimeSlotImagePath)
        .bind('click', function() { removeTimeSlot(id); })
        .addClass('hasPointer');
 
    // more code here to create and attach a DOM element containing
    // a string representation of the time slot and the removeTimeSlotLink
    // (...)
}

What happened when I tried to remove the time slots? The most recently added time slot would get removed all the time, even though I clicked the first and the second etc.

At this point, I knew it was due to some JavaScript function closure stuff, because I could see that my click event handler would call removeTimeSlot with the id of the most recently added time slot all the time.

But why was this happening? I made all kind of changes to the snippet, moved the variables around, made several temporary variables, but the problem persisted!

Then I searched around, and I discovered two things that I did not know about JavaScript (and would not have expected):

  1. Variables reside in the function in which they are declared.
  2. Functions get the closure of their containing function.

I am a C# guy, and in C# I know that an anonymous delegate gets the closure that it needs and nothing more. I also know that variables declared inside the scope of for instance a for loop are local to that loop. So doing stuff like this would not cause any unexpected behaviour:

foreach(var timeSlot in timeSlots) {
    // create local reference to be lifted out of this scope
    var timeSlotTemp = timeSlot;
 
    var button = new Button();
    button.Click += delegate { RemoveTimeSlot(timeSlotTemp); };
 
    // place button somewhere
    // (...)
}

To put it another way, it means that my code was actually equivalent to this (notice how all my variabled are “declared” at the top of the function):

// get array of selected time slots
var timeSlots = JSON.parse($('#selectedTimeSlotsJson').val());
var index;
var timeSlot;
var id;
var removeTimeSlotLink;
 
// create representation, including a link to remove each time slot
for(index = 0; index < timeSlots.length; index++) {
    timeSlot = timeSlots[index];
    id = timeSlot.id;
 
    removeTimeSlotLink = $('<img>')
        .attr('src', deleteTimeSlotImagePath)
        .bind('click', function() { removeTimeSlot(id); })
        .addClass('hasPointer');
 
    // more code here to create and attach a DOM element containing
    // a string representation of the time slot and the removeTimeSlotLink
    // (...)
}

To circumvent this, I created an inline function which would deliver the DOM element with the link. Something like this:

// get array of selected time slots
var timeSlots = JSON.parse($('#selectedTimeSlotsJson').val());
var index;
var timeSlot;
var removeTimeSlotLink;
 
var createRemoveTimeSlotLink = function(id) {
    // id is safe in here... :-)
    return $('<img>')
        .attr('src', deleteTimeSlotImagePath)
        .bind('click', function() { removeTimeSlot(id); })
        .addClass('hasPointer');
};
 
// create representation, including a link to remove each time slot
for(index = 0; index < timeSlots.length; index++) {
    timeSlot = timeSlots[index];
 
    removeTimeSlotLink = createRemoveTimeSlotLink(timeSlot.id);
 
    // (...)
}

- and from now on, to avoid unnecessary confusion, I will stop declaring my variables anywhere except the beginning of each function.

Lastly, I would like to give some shoutouts to the Mozilla folks for driving us all forward. Firefox 2 actually implements JavaScript 1.7, in which let was introduced as a keyword. let creates a new lexical scope and fixes one or more variables, which will then be promoted to a closure if necessary. Using let, my code would look like this:

// get array of selected time slots
var timeSlots = JSON.parse($('#selectedTimeSlotsJson').val());
 
// create representation, including a link to remove each time slot
for(var index = 0; index < timeSlots.length; index++) {
    var timeSlot = timeSlots[index];
 
    // introduce a new scope where id resides
    let (id = timeSlot.id) {
        var removeTimeSlotLink = $('<img>')
            .attr('src', deleteTimeSlotImagePath)
            .bind('click', function() { removeTimeSlot(id); })
            .addClass('hasPointer');
    }
 
    // more code here to create and attach a DOM element containing
    // a string representation of the time slot and the removeTimeSlotLink
    // (...)
}

- which is a lot simpler than the inline function version I ended up using. However, JavaScript 1.7 is not implemented by other browsers than Firefox 2 and Safari 3.x (according to Wikipedia) so it’s not really an option yet.