Errata

Web Development with Node and Express

Errata for Web Development with Node and Express

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
PDF, ePub, Mobi
Page xvi
2nd to last paragraph

As is: "Chapters 20 and 21 get your ready for the big day: your site launch."

"get your ready" seems wrong. Instead, perhaps write "get your site ready", or possibly "get you ready".

Note from the Author or Editor:
Corrected.

Andreas Wachowski  Jan 01, 2015 
PDF
Page IX
United States

Sentence "Just having gotten back from a trip to Lisbon, travel is on my mind, so the exmaple website I have chosen is for a fictional travel company in my home state of Oregon (the Western Meadowlark is the state bird of Oregon)."
The word "example" has a couple of letters transposed.

Note from the Author or Editor:
Change "exmaple" to "example".

Tom Bowersox  Mar 25, 2014 
ePub
United Kingdom

In Chapter 5
section: Cross-Page Testing

There are a number of minor mistakes with the example which will cause it to fail or not work if followed word for word.

1:
views/tours/hood-river.handlebars

the href link in <a class= "requestGroupRate" href= "/request-group-rate">
should either be "./request-group-rate"
or "tours/request-group-rate", the current example resolves to localhost:3000/request-group-rate which does not match with the routing in meadowlark.js

2:
The cross site test for oregon coast tour should not have the referrer as "'http://localhost:3000/tours/hood-river'" as it then won't fail the test, "We?ll see that one of our tests is failing?it failed for the ?Oregon Coast Tour? page, which should be no surprise, since we haven?t added that page yet.". It doesn't fail the test, as the test is wrong. Catch22- Who tests the tests!!


3:
The command "mocha -u tdd -R spec qa/tests-crosspage.js 2>/dev/null" when run on osx will result in a silent failure, unless the user has added mocha as a global node module using - npm install mocha -g (is this just my setup causing these problems?)

Note from the Author or Editor:
Fixed.

Joseph McLoughlin  Apr 20, 2014 
PDF, ePub, Mobi
Page 10
7th line in 5th paragraph

Actual: "[...] (even simple functionaity like resizing [...]"
Expected: "[...] (even simple functionality like resizing [...]"

Note from the Author or Editor:
Corrected.

Andreas Wachowski  Jan 01, 2015 
PDF
Page 12
2nd paragraph under "npm"

"manging" in line2 should be "managing"

Note from the Author or Editor:
Corrected.

REMOVED  Oct 14, 2014 
PDF
Page 16
End of 1st paragraph

The image tag example incorrectly uses an "href" attribute rather than the correct "src" attribute.

Note from the Author or Editor:
Duplicate; corrected in prior errata.

Matthew Erker  Oct 26, 2014 
PDF, ePub, Mobi
Page 16
1st line

"Serving static resources with Node is suitable for developent [...]"

developent -> development

Note from the Author or Editor:
Corrected.

Andreas Wachowski  Jan 01, 2015 
PDF
Page 16
1st paragraph, before code

notfound.html should be 404.html

Note from the Author or Editor:
This has been corrected.

Anonymous  Jun 10, 2015 
PDF
Page 16
Last sentence, 'Tip' inset

"You could change the route to be anything you want, and change the file to be anything you want. For example, if you had a different ?about? page for each day of the week, you could have files public/about_mon.html, public/about_tue.html, and so on, and provide logic in your routing to serve the appropriate page when the user navigates to http://localhostd:8088/about"

http://localhostd:8088/about should be http://localhost:8088/about

Note from the Author or Editor:
Fixed.

Anonymous  May 07, 2014 
Printed
Page 17
United States

The default call to serveStaticFile should use path '/public/notfound.html', based on the files created on the previous page.

Note from the Author or Editor:
Duplicate; corrected in prior errata.

Douglas Eichelberger  Oct 25, 2014 
PDF
Page 19
Second sentence of second paragraph of 'Scaffolding' section

The second sentence contains 'more a more' : "The advantage of this approach is that it
could generate more a more sophisticated framework...".

Note from the Author or Editor:
Delete the first "more" so that it reads "...could generate a more sophisticated framework".

Anonymous  Mar 29, 2014 
PDF
Page 21
2nd 'tip' section

"It will make it easier to sport redirect issues in your code, or
incorrect status codes, which are often overlooked. "

Type in sport, presumably should be spot.

Note from the Author or Editor:
Fixed.

Anonymous  May 07, 2014 
PDF
Page 24
command line after 6th paragraph

the command

npm install --save express3-handlebars

should now be (version number 3 was removed)

npm install --save express-handlebars

package name was changed "deprecated" warning occurs

Note from the Author or Editor:
Fixed. Updating to express-handlebars breaks the "weather partial" example in Chapter 7, requiring a change from partials.weather to partials.weatherContext. This has also been updated in the book.

John Bond  Sep 02, 2014 
PDF
Page 35
Last paragraph

Refer to the official Node module documentaion for more

typo in: documentaion

Ulf J�hrig  May 21, 2014 
PDF
Page 38
2nd paragraph in QA: Is It Worth It? section

There is:
"In web development, quality can be broken down into three dimensions"

It should be:
"In web development, quality can be broken down into four dimensions"

Note from the Author or Editor:
Corrected.

Przemysław Dąbek  Nov 02, 2014 
PDF
Page 39
2nd paragraph

There is:
"Aesthetics is the most subjective of the three dimensions"

It should be:
"Aesthetics is the most subjective of the four dimensions"

Note from the Author or Editor:
Corrected.

Przemysław Dąbek  Nov 02, 2014 
Printed
Page 42
3rd paragraph

"the property res.locals.showTests will set to be true" should be something like "the property res.locals.showTests will be set to true"

Note from the Author or Editor:
Corrected.

Anonymous  Nov 04, 2014 
PDF
Page 43
United States

On page 43 the text contains the following:

Note that Mocha and Chai get included, as well as a script called /qa/global-tests.js

However, in the code example just above on the same page it switches the word order in the file name:

<script src="/qa/tests-global.js"></script>

Further down on the same page, the text instructs you to create the tests-global.js file, so it appears this is a typo.

Note from the Author or Editor:
Corrected.

Greg Hendricks  Jul 30, 2014 
PDF, ePub, Mobi
Page 46
Third test in the 'Cross-Page Tests' code

In the code line

test('visiting the "request group rate" page dirctly should result ' +

change "dirctly" to "directly"

Note from the Author or Editor:
Typo corrected by author.

Andreas Wachowski  Jan 13, 2015 
PDF, Mobi
Page 46
First code line

Zombie 4.x no longer supports Node.js as per it's web page (Zombie 4.x is tested to work with io.js. For Node compatibility, consider using Zombie 3.x.).

A new install of zombie following the instructions of npm install --save-dev zombie will install the 4.x series which results in a silent crash when following instructions for running mocha with zombie later in the chapter. Instead, the latest version of zombie that works with node should be installed; version 3.1.1.

Replacing npm install --save-dev zombie with npm install --save-dev zombie@3.1.1 will result in a working installation with the current version (0.12) of node.

Note from the Author or Editor:
Good catch. I've updated the text to specify zombie@3.1.1. Of course all of this is going to change soon now that Node and io.js have finally reconciled, but the two projects finally merging is probably months out. I will update the book accordingly when that happens.

Brian Chow  May 12, 2015 
PDF
Page 47

Section on Cross-Page Testing

When working with express-handlebars which has Handlebars 3.0 merged into it (instead of the express3-handlebars@0.5.2), the cross-page testing breaks. The rest of the book code using the up to date version of express-handlebars otherwise works fine. Not sure what to change in the section on Cross-Page Testing to get it to work correctly.

mocha -u tdd -R spec qa/tests-crosspage.js 2>/dev/null


Cross-Page Tests
1) Requesting a group rate quote from the hood river tour page should populate the referrer field
2) requesting a group rate from the oregon coast tour page should populate the referrer field
3) visiting the "request group rate" page directly should result in an empty referrer field


0 passing (6s)
3 failing

1) Cross-Page Tests Requesting a group rate quote from the hood river tour page should populate the referrer field:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:170:19)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

2) Cross-Page Tests requesting a group rate from the oregon coast tour page should populate the referrer field:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:170:19)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

3) Cross-Page Tests visiting the "request group rate" page directly should result in an empty referrer field:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:170:19)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

Note from the Author or Editor:
This was related to a missing Handlebars {{#section}} that was necessary for jQuery ($) to be defined. This has been fixed in the text and the companion repository (on branch refactor, soon to replace branch master).

Anonymous  Mar 19, 2015 
PDF, ePub, Mobi
Page 51
8th line from bottom of page (excl. the footnote)

In "..., makes it a little easier to manager.", change "manager" to "manage".

Note from the Author or Editor:
Thanks for catching this! It's been corrected.

Andreas Wachowski  Jan 13, 2015 
PDF
Page 59
in the middle of page

There is:
res.set('Content-Type', 'text/plain\')

It should be:
res.set('Content-Type', 'text/plain')

Note from the Author or Editor:
Corrected.

Przemysław Dąbek  Nov 03, 2014 
PDF
Page 59
6th paragraph - res.send(body), res.send(status, body)

res.send(body), res.send(status, body)

In Express 4, res.send(status, body) is deprecated.

res.status(status).send(body) should be used.

Note from the Author or Editor:
Corrected.

Loren Abdulezer  Mar 19, 2015 
PDF
Page 63
4th sentence

Incorrect sentence reads: "So let's create a directory in our project called public (why we don't call it static will become evident in the next chapter). In that directory, we'll create home.html, about.html, notfound.html, a subdirectory called img, and an image called img/logo.jpg."

The code on page 66 references these files as "public/home.html", "public/about.html", and "public/404.html".

The correct sentence should read: "So let's create a directory in our project called public (why we don't call it static will become evident in the next chapter). In that directory, we'll create home.html, about.html, 404.html, a subdirectory called img, and an image called img/logo.jpg."

Note from the Author or Editor:
notfound.html corrected to 404.html.

Karl Herrick  Sep 08, 2014 
PDF
Page 64
top of page

The incorrect sentence reads: 'In your HTML files, reference the logo thusly: <img href="/img/logo.jpg" alt="logo">.'

This will cause an image rendering issue, because the HTML 'img' tag doesn't have an 'href' attribute. Additionally, the 'img' tag should be self closed.

The corrected sentence should read: 'In your HTML files, reference the logo thusly: <img src="/img/logo.jpg" alt="logo" />.'

Note from the Author or Editor:
href has been corrected to src. However, <img> tags are self-closing per HTML5, and therefore do not require a closing slash.

Karl Herrick  Sep 08, 2014 
PDF
Page 64
Example 6-12; the final code example

On line 6 of code example 6-12, there is an extra single quote after the string '</tours>', which throws the rest of the code example into reverse-string limbo and breaks the syntax highlighting for the (color) example in the PDF.

Note from the Author or Editor:
Corrected.

Cole Jackowski  Oct 16, 2014 
Printed
Page 64
United States

There should be no right paren after '/api/tours' in Example 6-11:

app.get('/api/tours'), function(req, res){
res.json(tours);
});

Note from the Author or Editor:
Corrected.

Joey Di Nardo  Nov 22, 2014 
Printed
Page 65
Example 6-13

var p = tours.some(function(p){return p.id == req.params.id });
if (p) {
if (req.query.name) p.name = req.query.name;
if (req.query.price) p.price = req.query.price;

properties p.name and p.price cannot be assigned due to p holding a boolean literal returned from Array.prototype.some()

Note from the Author or Editor:
Corrected. Since Array.prototype.find isn't available yet in ES5, I replaced this with Array.prototype.filer and then pulled off the first element (which will be undefined if no tour found).

Joey Di Nardo  Nov 22, 2014 
ePub
Page 70
United Kingdom

In the list item:

"lib/request.js
Exetnds Node?s http.IncomingMessage object to provide a robust request object. For information about all the request object properties and methods, this is where to look."

Extends is misspelt.

Note from the Author or Editor:
Fixed.

Joseph McLoughlin  Apr 20, 2014 
PDF
Page 77-78
Section on partials

When using the code samples for partials as described in the book, I get a 500 error. In the terminal the message lists:

Error: You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]
at Object.compile (...../meadowlark/site/node_modules/express-handlebars/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js:464:11)

I get the same error when using the code from the github repository (which is no surprise, it seems very same as the code in the book in this case).

I am using current version of express-handlebars@2.0.1

Note from the Author or Editor:
This is due to a new feature in express-handlebars that allows you to pass in a template dynamically. Unfortunately, to do so, you use the same context name of the partial...which is what I was using to pass in the regular context in the book. This has been corrected in the text (refresh coming soon) and the companion repository (currently on branch 'refactor', set to replace branch 'master' soon).

jakubvosahlo  May 24, 2015 
PDF
Page 89
near top

the code to include "body-parser" now causes deprecation warnings.
small amount of research shows that this code should now be preferred:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));

Note from the Author or Editor:
Corrected.

Anonymous  Oct 26, 2014 
Printed
Page 91
jquery section, $.ajax statment

Original text:

$.ajax({
url: action,

Changed to

$.ajax({
data: $(this).serialize(),
url: action



Note from the Author or Editor:
Good catch. This has been corrected.

hbbb  May 13, 2015 
PDF
Page 93
code listing

Instead of:

<label for="fieldEmail" class="col-sm-2 control-label">Email</label>
<div class="col-sm-4">
<input type="email" class="form-control" required
id="fieldName" name="email">
</div>

It should be:
<label for="fieldEmail" class="col-sm-2 control-label">Email</label>
<div class="col-sm-4">
<input type="email" class="form-control" required
id="fieldEmail" name="email">
</div>

Notice the id of the input element is "fieldEmail".

This errors occurs several time before.

Note from the Author or Editor:
Corrected.

Anonymous  Feb 09, 2015 
PDF
Page 94
code snippet

There is:
year: now.getFullYear(),month: now.getMont()

It should be:
year: now.getFullYear(), month: now.getMonth()

Note from the Author or Editor:
Corrected.

Przemysław Dąbek  Nov 03, 2014 
PDF
Page 104
near top

use of "express-session" now causes deprecation warnings
small amount of research shows this should be preferred:

var session = require('express-session');
app.use(session({
secret : '<mysecret>',
saveUninitialized : true,
resave : true
}));

Note from the Author or Editor:
Corrected.

Anonymous  Oct 26, 2014 
PDF
Page 105
whole page

Just like to say I think this is a truly great book, by the way.

This whole section of including the "bootstrap-flash" functionality doesn't quite hang together. Firstly, you say at the top of the page "so make sure you have Bootstrap linked in." I had to do quite a bit of research about what Bootstrap actually is! Secondly you don't say where the Bootstrap bits and pieces should be put.
Thirdly, you omit to include code for VALID_EMAIL_REGEX or NewsletterSignup.
Getting confused at this point, I downloaded your chapter 9 "code-state" from github... but it doesn't provide a working implementation with this "bootstrap-flash" incorporated.
So then I downloaded your chapter 11 "code-state" (next one). After a bit of tweaking I was able to use this. And after a bit of tweaking I was able to copy its structure so that the boostrap stuff was where you put it, and my version of meadowlark.js included the necessary extra code.
But I had to copy across your version of main.handlebars because with the version I had developed, although the appropriate "bootstrap-flash" messages were displayed, they couldn't be dismissed (this despite me trying to understand and tweak the code from looking at your main.handlebars)...

Note from the Author or Editor:
The sample code in this chapter is intended to be more of a sample than a complete ready-to-use implementation. It sounds like that wasn't clear in the text, so I have updated the text to indicate the nature of these code samples. I also included an implementation of VALID_EMAIL_REGEX based on the W3C HTML5 email regex. I'm also taking notes from this errata for more substantive changes in the next edition.

Anonymous  Oct 26, 2014 
, Printed, PDF, ePub, Mobi, , Other Digital Version
Page 114
4rd paragraph

The command(s) in the paragraph states:

body-parser (npm install --save body-parser, app.use(require(bbody- parser)());)

Note the typo in 'bbody'. It should be:

body-parser (npm install --save body-parser, app.use(require(body- parser)());)

Also, please add a newline like the rest of the middleware (makes it a bit clearer):

body-parser (npm install --save body-parser,
app.use(require(body- parser)());)

Note from the Author or Editor:
Corrected -- left on one line for formatting reasons.

Tito Ciuro  Aug 31, 2014 
PDF
Page 130
top

the code as stated generates an error because the variable "http" is not defined anywhere at this point (if one is following along, or even if one downloads the chapter 11 code from github).
Presumably should be replaced by
app.listen(app.get('port'), function() {
console.log('Express started in ' + app.get( 'env') + 'mode on http://localhost:' + app.get('port') + '; press Ctrl-C to terminate.');
});

Note from the Author or Editor:
While http.createServer and app.listen are essentially interchangeable, I do agree that the book's use of these two methods is inconsistent. I replaced the calls to http.createServer with app.listen, except for Chapter 18, where I explicitly import https (as far as I know, there's no secure equivalent to app.listen).

Anonymous  Oct 26, 2014 
PDF
Page 131
last line

There is:
"the increased poularity of cloud computing"

It should be:
"the increased popularity of cloud computing"

Note from the Author or Editor:
Corrected.

Przemysław Dąbek  Nov 05, 2014 
PDF
Page 136
this whole bit (and before)

in this chapter 12 (Production concerns) you started getting me rather confused because for some reason you revert to using the "http" var, which has not been used since the Meadowlark site was first started being built.

To begin with this was not a problem, but on p. 136, when you go into recovering from en error in a cluster, you define a var "server" which has then to be referenced if a worker fails.

I worked around this like this, but obviously I don't know whether it's the right solution...:

var server;
function startServer() {
server = app.listen(app.get('port'), function() {
console.log('Express started in ' + app.get('env') + ' mode on http://localhost:' + app.get('port')
+ '; press Ctrl-C to terminate.');
});
}

Note from the Author or Editor:
Corrected.

Anonymous  Oct 26, 2014 
PDF
Page 144
top

these lines cause an error:

fs.existsSync(dataDir) || fs.mkdirSync(dataDir);
fs.existsSync(vacationPhotoDir) || fs.mkdirSync(vacationPhotoDir);

... for the simple reason that require( 'fs' ) hasn't been used in the Meadowlark project.
In fact simple experimentation shows that you have to first go require( 'http' ) for require( 'fs' ) to work. Why, I have no idea!

Note from the Author or Editor:
Corrected. I added a reminder to make sure the fs library is imported. Its not necessary to import http before importing fs, as Mike suggests.

Anonymous  Nov 02, 2014 
Printed
Page 144
12th line of the code block

if(err) return res.redirect(303,'/error');

This line should be removed, otherwise the second error handler (which is more extensive) would never fire.

Note from the Author or Editor:
Corrected.

Bart Louwers  Dec 10, 2014 
Printed
Page 144
19th line of code block

Pelase -> Please

Note from the Author or Editor:
Corrected.

Bart Louwers  Dec 10, 2014 
Printed
Page 146
3rd paragraph

'Traditionally, the world "database"' should read 'Traditionally, the word "database"'

Note from the Author or Editor:
Corrected.

Anonymous  Nov 06, 2014 
PDF
Page 152
near top

On this page one is hoping to see some magic with the Mongodb cloud-based database.
Instead, I got an error about undefined variable not having an attribute "length".
This refers to this line: if(vacations.length) return;, in "Vacation.find..." with the initial raw data (3 records).
And in fact, you don't introduce this variable "vacations" at all, either in meadowlark.js or in vacations.js.
Nor do you in fact say where the "Vacations.find..." function is supposed to go (I assumed meadowlark.js).
I haven't yet found a solution to this but I assume "vacations" should be introduced at some point as an empty array... also I'm far from clear about how, exactly the function parameter is fed to the Vacation.find method...

Working around the above problem I put
if(typeof vacations !== 'undefined'){
return;
};
... but this then caused a similar error: "Cannot call method 'map' of undefined" (part of the route functionality for '/vacations').

Note from the Author or Editor:
Corrected. The vacations variable is the second argument passed into the callback. The fact that its undefined indicates that there was an error; the problem with this code is there is no error handler, which I have corrected.

Anonymous  Nov 02, 2014 
PDF
Page 212
Deutschland

In the chapter "Security" you are describing how to purchase a private key. At the end of the chapter the generated private key is downloaded (via HTTPS) from the signing company.

In my opinion the public/private key-pair should always be generated by yourself and only a certificate signing request (CSR) should be sent to the signing authority. Otherwise you can't be sure that you are the only one knowing this private key.

I haven't checked with all certificate signing providers, but with all the providers I had business with, they accept only CSRs, and don't generate a private key for you.

Note from the Author or Editor:
Corrected.

Ulf J�hrig  Jul 08, 2014 
ePub
Page 228
2nd code sample

in the middleware function to demonstrate cluster usage the next function is not called from within the function and this causes the server execution to stall. adding next(); prior to the closing braces resolves this issue.

Note from the Author or Editor:
Corrected.

Anonymous  Aug 11, 2014 
PDF
Page 228
Bulgaria

"Twitter" pop-ups out of nowhere in the middle of integrating Facebook authentication.

"Now we have the path /auth/facebook; visiting this path will automatically redirect the visitor to Facebook’s authentication screen (this is done by passport.authenticate('facebook')), step 2 in Figure 18-1. Note that we override the default callback URL here: this is because we want to include information about where we came from.
Since we’re redirecting the browser to Twitter for authentication, we might want some way to come back to where we started. Once the user authorizes with Twitter, the browser will be redirected back to your site."

Note from the Author or Editor:
Corrected.

Mario Georgiev  Nov 14, 2014 
Printed
Page 228
code sample

The second call to app.get() passes the callback function to passport.authenticate() instead of to app.get(). That doesn't work. Unfortunately the lack of a JS type checker makes the error difficult to find.

Existing code:

registerRoutes: function(){
app.get(...);
app.get('auth...', passport.authenticate('facebook',
{ failureRedirect: ...},
function(req, res){
// we only get here on successful authentication
...
}
));
}

Correction by moving a ')':

registerRoutes: function(){
app.get(...);
app.get('auth...', passport.authenticate('facebook',
{ failureRedirect: ...}),
function(req, res){
// we only get here on successful authentication
...
}
);
}

Note from the Author or Editor:
This has been corrected in the text (along with some other improvements to the authentication flow), and the companion repo (on branch 'refactor', soon to replace branch 'master').

srhoag  Jun 06, 2015 
PDF
Page 233
Bulgaria

"...the ability to tweet abut the page you're on..."
"abut" probably should be "about"?

Note from the Author or Editor:
Corrected.

Mario Georgiev  Nov 14, 2014