Node.JS and Heroku

Sam Kenny
Sam Kenny
Jan 12, 2014 · 3 min read

I am following Node:Up and Running to learn about Node.JS and extending what I have gleaned from this book, and learned on the excellent Javascript courses at O’Reilly School of Technology, so that I can deploy the book example apps on a Heroku dyno. I like the way the book is written, but there are some really frustrating gaps — thus far. At least for a node.js n00b like me.

If you got stuck like me, here are some fixes. Most of these stem from a) typos and b) I assume, earlier versions of EJS and Express.

Chapter 2 — Example 2–1. A test for the POST API

var http = require('http'), assert = require('assert');
var opts = {
host: 'localhost',
port: 8000,
path: '/send',
method: 'POST',
headers: {'content-type':'application/x-www-form-urlencoded'}
var req = http.request(opts, function(res) {
var data = "";
res.on('data', function(d) {
data += d;
res.on('end', function() {
assert.strictEqual(data, '{status:"ok", message:"Tweet received"}');
Chapter 2 - Examples 2-17 through 2-22. Getting the Chirpie site to work.First off, you need to install EJS. Do so from where your project is - so in my case, run it in the 'my app folder' - see below.MyApp
├── app.js
├── public
└── views
└── partials
Run:npm install ejsIn the node_modules folder you will see a folder for ejs.What the book does not state is that the example code needs to be saved in files with a .ejs extension. So index.ejs should exist in the views folder and chirp.ejs in the partials. In addition, the body tag is no longer support so you need to break the layout of the page into the 'top' and the bottom'.The folder structure, with files, now looks like this:MyApp
├── app.js
├── public
├────── style.css
└── views
├── index.ejs
├── layoutBottom.ejs
├── layoutTop.ejs
└── partials
├── chirp.ejs
└── stylesheet.ejs
The content of the files is as follows:


var express = require('express');
var app = express();
// Required to load the css stylesheet file defined in locals
app.use(express.static(__dirname + '/public'));
// New for Express 3.0
app.set("view engine", "ejs");
var tweets = [];app.get('/', function(req, res) {
var title = 'Chirpie',
header = 'Welcome to Chirpie';
res.render('index', {
locals: {
'title': title,
'header': header,
'tweets': tweets,
stylesheets: ['style.css']
// bodyParser is 'middleware''/send', express.bodyParser(),
function(req, res) {
if (req.body && req.body.tweet) {
tweets.push(req.body.tweet)if (acceptsHtml(req.headers['accept'])) {
res.redirect('/', 302);
else {
res.send('{status:"ok", message:"Tweet received"}');
else {
// no tweet?
res.send('{status:"nok", message:"No tweet received"}');
app.get('/tweets', function(req,res) {
// A small function to check for text/html in an accept header
function acceptsHtml(header) {
var accepts = header.split(',');
for (i=0; i < accepts.length; i++) {
if (accepts[i] == 'text/html') {
return true;
return false;
index.ejs<% include layoutTop %>
<form action="/send" method="POST">
<input type="text" length="140" name="tweet">
<input type="submit" value="Tweet">
<% include partials/chirp %>
<% include layoutBottom %>


<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<% include partials/stylesheet %>
<title><%= title %></title>
<h1><%= header %></h1>




<p><%= tweets %></p>


<link rel="stylesheet" href="<%- stylesheets %>">Now when you run you should see the the Chirpe page with an input box.  Enter some text and hit 'tweet'.  You should see each tweet (aka 'chirp') appear below as a comma-delimited string.

Sam Kenny’s a(musing)

Random tech articles and tidbits of interest

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store