Susan Harkins (297) [Avatar] Offline
#1
Please post errors found in the published version of Node.js in Action, Second Edition here. If necessary, we'll publish a comprehensive list for everyone's convenience. Thank you!

Susan Harkins
Errata Editor
303763 (9) [Avatar] Offline
#2
Following are a few items that may need to be addressed:

- Page 102, Section 5.9

This really does not reflect Loopback 3.0. Now you install “loopback-cli” with nom Instead of “strongloop”. Also the command is now “lb” instead of “slc”. So it’s also “lb:model”, etc.

- Page 109, section 6.1.1

Express is not actually built with Connect any more. This used to be the case before Express 4. However it still supports middleware using Connect conventions.

-Page 119, figure 6.6

The directory was not updated from Jade to Pug.
289422 (4) [Avatar] Offline
#3
Incorrect code. Missing `(err, result)` from anonymous function declaration.
Page 206 - Listein 8.3.

`, () => {
if (err) throw err;
const id = result.rows[0].id;
console.log('Inserted row with id %s', id);
});
289422 (4) [Avatar] Offline
#4
Subject - specifying tag content - Pug

Suggested way is not working for current Pug version.

If the HTML tag, such as the style and script tags, accepts only text (meaning it
doesn’t allow nested HTML elements), then the | characters can be left out entirely, as
the following example shows:
style
h1 {
font-size: 6em;
color: #9DFF0C;
}


Current working way - using dot at the end of the tag:

style.
h1 {
font-size: 6em;
color: #9DFF0C;
}


https://stackoverflow.com/questions/21765107/how-to-use-the-style-tag-with-jade-templates
289422 (4) [Avatar] Offline
#5
Chapter 12 - Listing 12.2 - Electron

Using the remote library is dated.

let remote = require('remote')


Instead this is what is working now:

let { remote } = require('electron');
233628 (1) [Avatar] Offline
#6
Chapter 12. Conquering the desktop with Electron

12.3.2 Installing the Dependencies

.babelrc file is missing a setting:

{
"plugins": [
"babel-plugin-transform-class-properties",
"transform-react-jsx"
],
"presets": ["es2015"]
}
338322 (1) [Avatar] Offline
#7
Chapter 3.1, Pg. 52 under "A Simple Server"

There is a small error in the app.listen portion of the example code -- there needs to be an opening curly brace in the anonymous function declaration and a closing parentheses at the end of the block before the semicolon:

```
const express = require('express');
const app = express();

const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(port, () =>
  console.log(`Express web app available at localhost: ${port}`);
};

```

last section should be:
app.listen(port, () => {
  console.log(`Express web app available at localhost: ${port}`);
});
alex.young (10) [Avatar] Offline
#8
Thanks for the errors and changes everyone has suggested so far. I'm going to work through them and start building up a proper errata over the next few days.

If there are any other issues just post to this thread.
Susan Harkins (297) [Avatar] Offline
#9
An updated errata list for Node.js in Action, Second Edition is available at https://manning-content.s3.amazonaws.com/download/0/196c925-e04c-470d-a8d7-6551ba8cc3ee/Young_Node.jsinAction_Err1.html. Thanks!

Susan Harkins
Errata Editor
Manning Publications
315401 (9) [Avatar] Offline
#10
After listing 6.10 it says "Now when you use a browser to access /post on your application, you’ll be able to add entries."

Actually, the app won't even start until completing the section on the next page titled "ADDING ENTRY-RELATED ROUTES".

shoutbox/app.js:28
app.get('/post', entries.form);
                 ^

ReferenceError: entries is not defined
315401 (9) [Avatar] Offline
#11
The start of section 6.2.4 promises to "Implement pagination", but pagination is only partly implemented later in section 6.2.9, and never in the UI as in the "full-app" in the code repo.
315401 (9) [Avatar] Offline
#12
Needless confusion in Chapter 6. Is it a "post" or is it an "entry"? Pick one: entry

For example: the entries route (at /post (singular)) uses the post.ejs form to create an "entry", but the api uses /api/entries (plural) to create entries
315401 (9) [Avatar] Offline
#13
section 6.2.4 (pp 132-134) makes use of res.error which isn't defined until section 6.2.6 (p 143)
315401 (9) [Avatar] Offline
#14
Listing 6.18

const User = require('./models/user');


This line redefines User; is an error.
315401 (9) [Avatar] Offline
#15
Section 6.2.6, pp 142-143


The res.message function provides a way to add messages to a session variable from
any Express request. The express.response object is the prototype that Express
uses for the response objects. Adding properties to this object means they’ll then be
available to all middleware and routes alike. In the preceding snippet,
express.response is assigned to a variable named res to make it easier to add
properties on the object and to improve readability.


The code this paragraph refers to is not present; this paragraph is the only appearance of express.response in the whole book.
315401 (9) [Avatar] Offline
#16
Snippet on page 144 includes
app.use(express.methodOverride());

but methodOverride is only covered in Appendix C.



This code snippet on page 147 was already done at the start of section 6.2.7.

const login = require('./routes/login');
...
app.get('/logout', login.logout);





Listing 6.29 should include the prior edits to app.use(session(...))

app.use(session({
  secret: 'secret',
  resave: false,
  saveUninitialized: true
}));



Same listing, the line
app.use(app.router);

is explained nowhere.


Section 6.2.9 TESTING USER DATA RETRIEVAL on page 152: the curl command will succeed no matter what you send for user:pass, because authentication is not actually enabled.

In the full-app code repo, api.auth is different
exports.auth = (req, res, next) => {
  req.remoteUser = auth(req);
  next();
};

but also doesn't prevent unauthorized access.

Testing api posting later results in redirect to /, because of no remoteUser, but the post is created anyway.

The fail occurs because when User.authenticate is called with an unknown user, the callback is called without args (because !user.id), and so both user and err are undefined. :-{ The root cause is further up the chain, probably somewhat because getId never triggers an error.



p 155, TESTING THE ENTRIES ROUTE fails because page() was never required in app.js

532364 (1) [Avatar] Offline
#17
To perform Basic authentication, install the basic-auth module: npm install --save basic-auth. Next, create the ./routes/api.js file, and require both Express and the user model, as shown in the following snippet. The basic-auth package accepts a function to perform the authentication, taking the function signature (username, password, callback). Your User.authenticate method is a perfect fit:


This doesn't make any sense since the basic-auth package doesn't accept a function to perform the authentication. I assume that req.remoteUser was intended to be checked in the api.user method at some point to determine whether the User should be fetched at all or if a 401/403 should be sent instead.

if (!req.remoteUser) return res.sendStatus(401);


Adding this line to api.user returns something along the lines of what we're looking for I think:

exports.user = (req, res, next) => {
    if (!req.remoteUser) return res.sendStatus(401);
    User.get(req.params.id, (err, user) => {
        if (err) return next(err);
        if (!user.id) return res.sendStatus(404);
        res.json(user);
    });

}

539022 (2) [Avatar] Offline
#18
page 291 --> memory leak

this.handleResult.bind(this) === this.handleResult.bind(this) // output false, because bind will create new function all the time

Taking it into account, there is no use in removing handleResult in componentWillUnmount method, since we try to remove something new from listener.

We should create handler in constructor and reuse it in componentWillUnmount to free resources

Thx
-Yura