Node Tutorial Part 4

2010-11-22 00:00:00 +0000 by Alex R. Young

Welcome to part 4 of Let's Make a Web App, a tutorial series about
building a web app with Node. This series will
walk you through the major areas you'll need to face when building your
own applications. These tutorials are tagged with

Previous tutorials:

In this part I'll add so much stuff you should get up and make a cup of
tea first.

By the end of the tutorial (or right now if you check the code out from
git), you'll have something that looks like this:

Not all of the code is in this tutorial text: I've shortened a few code
examples and haven't included any CSS. It's all available in the
repository, so download it and open it up in your editor.

Updating Expresso

Expresso has been updated to 0.70. Upgrade yours with npm update
. The version we started out with is no-longer fully
compatible with the
, particularly
the beforeExit method handling.

Rendering Templates

The document list method (/documents) should render a list
of documents that we can edit. To do this, add an appropriate
render invocation:

res.render('documents/index.jade', {
  locals: { documents: documents }

... and a corresponding template:

  - for (var d in documents)
    li= d.title

Remember that our templates are written with Express's default language,


Using Jade is strange at first, but it's actually pretty easy to get the
hang of. Here are the key things to remember:

Note that it's generally a good idea to escape as much as possible to
reduce the chance of XSS attacks.


Jade and Express make partials -- little snippets of reusable templates
-- easy. Here's the new document (views/documents/new.jade) template:

h2 New Document
form(method='post', action='/documents')
  !=partial('documents/fields', { locals: { d: d } })

The partial is rendered by calling partial(template file name,
. The output isn't escaped because we'd just see HTML
tags if it was -- the user-defined fields within it will be escaped, so
it's still safe.

New and Edit Forms

Before creating the mind-blowingly awesome Ajax interface, let's make
some simple templates. Our REST API defined create and update methods,
so we should make corresponding new and edit methods to provide a user

I usually split forms like this into three templates. One is a reusable
partial that contains the form fields. The other two are new and edit
templates that contain the appropriate form code to wrap around the

The new form was used as an example above. The edit form,
views/documents/edit.jade looks like this:

h2 Edit Document
form(method='post', action='/documents/' + d.id)
  input(name='document[id]', value=d.id, type='hidden')
  input(name='_method', value='PUT', type='hidden')
  !=partial('documents/fields', { locals: { d: d } })

That's the same as new, but with added hidden input fields. The
_method field allows us to POST this form to
a put route, which came from the RESTful API we designed
last week.

The fields partial (views/partials/documents/fields.jade) is simple as

  label Title:
    input(name='document[title]', value=d.title || '')
  label Note:
      =d.data || ''
  input(type='submit', value='Save')

By this point you should be getting a feel for Jade. I'm not a die-hard
haml/Jade fan, but as you can see these examples have been very light on

New and Edit Back-end Methods

All the new and edit server-side methods do is load a document and
render the forms:

app.get('/documents/:id.:format?/edit', function(req, res) {
  Document.findById(req.params.id, function(d) {
    res.render('documents/edit.jade', {
      locals: { d: d }

app.get('/documents/new', function(req, res) {
  res.render('documents/new.jade', {
    locals: { d: new Document() }

The new method makes a blank Document to keep the form
templates happy.

Mongo IDs

Did you notice that the templates refer to d.id? Mongoose
makes _id fields by default, which are
ObjectID data types. This doesn't look too great on the
web, so I made this getter method and added it to model.js:

getters: {
  id: function() {
    return this._id.toHexString();

By using toHexString we get nice IDs like

Update and Delete

Both the update and destroy methods load the document first then call
save or remove on it. The general pattern is
as follows:

app.put('/documents/:id.:format?', function(req, res) {
  // Load the document
  Document.findById(req.body.document.id, function(d) {
    // Do something with it
    d.title = req.body.document.title;
    d.data = req.body.document.data;

    // Persist the changes
    d.save(function() {
      // Respond according to the request format
      switch (req.params.format) {
        case 'json':


Delete is basically the same, except remove is called
instead of save.

Delete JavaScript

One quirk of our API is we're using Express's del method,
which means it'll expect to see _method="delete" in the
post parameters. Most frameworks implement this by using a bit of
client-side JavaScript.

As I said in the first tutorial, we're going to use jQuery. jQuery can
be included by editing the layout.jade template to look like this:

    title= 'Nodepad'
    link(rel='stylesheet', href='/stylesheets/style.css')
    script(type='text/javascript', src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js')
  body!= body
    script(type='text/javascript', src='/javascripts/application.js')

This also includes our JavaScript at the bottom. Express is already set
up to serve static files that are in the public directory.

The client-side delete JavaScript works by:

  1. Using confirm() to check if the user really wanted to
    delete the document
  2. Dynamically inserting a form with a hidden input called
    _method with a value of delete
  3. Submitting the form

Of course, this is simple with jQuery. I wrote the whole thing as one
chained set of instructions:

$('.destroy').live('click', function(e) {
  if (confirm('Are you sure you want to delete that item?')) {
    var element = $(this),
        form = $('');
        method: 'POST',
        action: element.attr('href')
        'name': '_method',
        'value': 'delete'

It uses a live event delegate so we don't litter our client-side HTML
with inline JavaScript.

The Index Page

I've made the default action redirect to /documents, and
the document index action do this:

h1 Your Documents

  a(class='button', href='/documents/new') + New Document

  - for (var d in documents)
      a(class='button', href='/documents/' + documents[d].id + '/edit') Edit
      a(class='button destroy', href='/documents/' + documents[d].id) Delete
      a(href='/documents/' + documents[d].id)

This is an example of using an iterator in Jade. A preferable approach
would be to use partial's collection support, but it's useful to
demonstrate how control blocks within templates work in Jade.


As of commit

we now have a basic working notepad.

Check out the latest version of
Nodepad and see what cool features you can add before I continue the series next week.