By Developers, For Developers

Historical errata for Node.js the Right Way

PDF PgPaper PgTypeDescriptionFixed onComments
16SUGGEST

Strings and regexes in the code samples are italicized. Unfortunately, italicizing a backslash makes it look a lot like a pipe symbol. I suggest using some other formatting option—maybe just plain text—for those items or backslashes specifically.

119ERROR

Line 20 reads:
Array.prototype.slice.call(null, arguments);

should read:

Array.prototype.slice.call(arguments);

This same error is in other areas, but correct on line 15 above on the same page.

222ERROR

The many calls to yield in the file bundle.js need to be changed to Fiber.yield()

45SUGGEST

You are using publisher.bind when binding to the port. I had an issue where I had a typo that caused the server to exit and I could no longer bind to that port and get a “Socket is busy” error. I opted to do a little bit of research and found and article that suggested bindSync over bind. Changing that seemed to work, but I am unsure if there are other downsides.

25ERROR

On the code example, the Date.now() method is used, which returns the number of seconds since 1 January 1970 00:00:00 UTC. However, on the description of the output (page 27), it seems like it is from the Date.prototype.toString() method. Maybe the example should be changed to `new Date(Date.now())`.

40TYPO

(I’m looking at the ePub version, not the PDF.)

In the code for the watcher-spawn-parse.js, as rendered in my ePub, I do not see the forward-slashes around the regex in the second embedded function. What I see in the ePub (on my Nook Tablet) is:

let parts = output.split( /s+ );

This generates an error when I run it. Going to the source code that is linked, I can see that the line should be:

let parts = output.split(/\\s+/);

Just a minor typo, really, but it should probably be fixed. ;) Did the gerbils screw this up when they generated my ePub, or is this something with my reader?

28SUGGEST

I’m a windows user, so instead of using telnet, I use netcat. and instead of using the windows command prompt, I use git bash since it provides me with a unix like shell script environment.

The current version of node.js I’m using is v 0.10.22.

Now that this is out of the way, here’s the situation.

When I execute the code as is in git bash and then connect using netcat.. It works fine. If I make a change to the watched file, it will report it to my netcat window.

But, when it’s time to close the connection, I do a ctrl-c in netcat and it obviously stops the connection.

But in git bash, my node js code throws an unhandled error event message, thus not executing the close event code.

To compensate for the error and ensure the close event executes, I have to do add the following:

connection.on(‘error’, function(err) {});

If this is available, then, I get proper closure.

Makes sense? what do you think? Is this how it’s supposed to be? A bug in Node.js? a problem with my environment?

49TYPO

getting errors when trying to execute the ldj.js file, had to convert all let to var.

79SUGGEST

After running “node —harmony import-books.js” the text suggests that there will be an ECONNRESET error. On my circa-2012 MacBook Pro, it ran without a hitch the entire time. It might be worth mentioning that an error here isn’t definite.

84TYPO

“If this is your first time running this program, there won’t be a _desing/books document yet and the request will return a 404 Not Found status code.” in first paragraph.

“_desing/books should be ”_design/books"

92ERROR

When I run “nodemon —harmony server.js” on the downloaded source code, I get the following error:

/Users/bcbrown/node/ntrw/web-services/b4/lib/bundle.js:99
Q.async(function *(){
^
SyntaxError: Unexpected token *

I was unfamiliar with the * operator attached to a function so I did some digging. I discovered that it’s for JavaScript generators and got support in Node.js v0.11.2 released 5/13/2013. Unfortunately, “brew” and the Node.js Web site only offer v0.10.22 stable. Page 7 of the PDF states that “This book assumes you’re using the latest stable version of Node.js.” and nowhere in the chapter do you indicate otherwise.

I’ll use nvm to get unstable so I can switch around but this is definitely a problem that should be called out or remedied in the source code.

89SUGGEST

You should clarify that the reader should run “npm install” with no arguments to install dependencies declared in package.json. Previously in the book such a suggestion would have “$ npm install” called out through color and bolding rather than a clause in a sentence.

When I got to page 92 and entered “nodemon —harmony server.js” in the Terminal, I got a series of errors indicating that dependencies were not installed. I had to backtrack through a series of steps that led me to recall that dependencies resided in package.json so there must be a way to install those locally to the project. I found it on the Web and then read through the chapter more carefully. I was tempted to throw in the towel towards the end but am glad I persisted because dependency management is such a vital, practical topic.

92ERROR

Using the downloaded code and a straight install of CouchDB (which has worked on all examples heretofore), I cannot get any of the search API examples to work. I am using v0.11.2 via nvm because of the earlier problem with lack of generator support in the suggested v0.10.22.

I keep getting the following response from CouchDB:
{
error: “bad_request”,
reason: “invalid_json”
}

I set the logging level to “debug” as recommended by CouchDB and I got more information:

[debug] [<0.116.0>] OAuth Params: [{“startkey”,“%22Croc%22”},
{“endkey”,“%22Croc%EF%BF%B0%22”},
{“group”,“true”}]
[error] [<0.116.0>] attempted upload of invalid JSON (set log_level to debug to log it)
[debug] [<0.116.0>] Invalid JSON: {{error,
{1,
“lexical error: invalid char in json text.\
”}},
“%22Croc%22”}
[info] [<0.116.0>] 127.0.0.1 - - GET /books/_design/books/_view/by_subject?startkey=%2522Croc%2522&endkey=%2522Croc%25EF%25BF%25B0%2522&group=true 400

I tried removing the stringify call from the field-search.js so that the URL-escaped double quote wouldn’t be included but got the same error. I also took the incoming URL that CouchDB logged and ran it through the dbcli.js program in a previous chapter so I could monkey around more directly. Everything in the JSON looks valid to me but I’m stumped.

57TYPO

Based on book example received:
TypeError: Array.prototype.slice called on null or undefined

made following change to receive expected output:
zmq-filer-rep-cluster.js:
dealer.on(‘message’, function() {
- let frames = Array.prototype.slice.call(null, arguments);
+ let frames = Array.prototype.slice.call(arguments);
router.send(frames);

18ERROR

Shebangs with more than one argument don’t work as expected on Linux, so the example doesn’t work directly on all “Unix-like systems”. A note about that might be of use to readers unaware of that incompatibility

92SUGGEST

The “module.exports = function” pattern appeared before, at page 72 (on the PDF). Maybe the explanation of what it is should be moved to its first instance in the book

72SUGGEST

The example code on page 72 breaks when using Cheerio 0.13.0 (latest). Cheerio 0.12.4 seems to work.

5ERROR

I try with a linux distro and there is no ‘close’ event sent. ‘exit’ event works

72ERROR

In order to get the subjects out of The Art of War, I had to change the value of subjects to the following:
$(‘pgterms\\\\:ebook dcterms\\\\:subject rdf\\\\:Description rdf\\\\:value’).map(collect)

This works using Cheerio 0.13.1.

72ERROR

With the latest version of Cheerio the authors and subjects return a Cheerio array, not a plain array. It will not compare properly to the test JSON object. Add a “.toArray()” call to the end of those property assignments to convert them.

26SUGGEST

Postgres often runs on port 5432. This can cause confusion when using telnet. Perhaps use another high port like 8124 from the node docs.

15ERROR

The code as shown shouldn’t work; the variable “output” has the wrong scope. The quick fix is to change the comma on the proceeding line to a semicolon, but a better fix would be:

let output = ’‘;
fs.watch(filename, function() {
let ls = spawn(’ls’, [‘-lh’, filename]);

15SUGGEST

The number of fields produces by the ls command depend on the locale (if POSIX ls is used). The file’s name may be the 8th, 9th, or another field.

I suggest you not only refer to to “Unix-like”, but also to the POSIX locale, on page xii. You could add on that page ‘to ensure the examples work as expected, set the environment variable “LC_ALL” to “POSIX”’. (You might want to consider using UTC for all time-related examples, but I don’t know if you have any.)

15SUGGEST

My bad, please ignore #76474; I had the blocks not nested when I looked. I looked again; should have done that before posting.

58TYPO

The last command on the page is missing the target file. Currently, it is printed as:

“node —harmony zmq-filer-req-loop.js”

To make it work, I changed it to:

“node —harmony zmq-filer-req-loop.js target.txt”

57SUGGEST

Maybe you should handle errors when binding router and dealer?

I’ve had a permission error when trying to bind the ipc endpoint. It took me about an hour to understand what was going on. I get it better after adding an error callback on bind call.

72ERROR

On line 10 of rdf-parser.js, the code should be passing a second argument of { xmlMode: true } to cheerio.load().

Versions 0.13 and newer of cheerio behave differently when parsing XML than they do parsing HTML, and one of those differences is in the handling of self-closing tags. Without XML mode being enabled, these newer versions of cheerio incorrectly parse the rdf:value tags that contain the book’s subjects as children of the dcam:memberOf tag, rather than as its siblings. This breaks the example code, as observed in errata #76396 and #58781.

The suggested fix enables XML mode, which allows arbitrary tags to be self-closing and causes the example RDF to parse correctly. It’s preferable to the fix from #76396 because it avoids adding an extra “U” element from an unrelated rdf:value element. This fix was tested on 0.12.4, 0.13.1 and 0.14.0.

25ERROR

On page 27 we read that the expected output of the net-watcher.js script described on pages 25 and 26 is:

File ‘target.txt’ changed: Sat Jan 12 2013 12:35:52 GMT-0500 (EST)

To produce this result code on page 25 should read:

connection.write(“File ’” + filename + “’ changed: ” + new Date() + “\
”);

Instead of:

connection.write(“File ’” + filename + “’ changed: ” + Date.now() + “\
”);

Date.now() produces a numeric timestamp, not a human-readable one as presented on page 27.

75SUGGEST

I was unable to run the ‘node —harmony $(which nodeunit) test/’ command successfully on Windows 7. I ended up editing the userprofile\\AppData\\Roaming\
pm\
odeunit.cmd and nodeunit files and added ‘—harmony’ after the node.exe calls to get through the example (e.g. ‘“$basedir/node” —harmony ’).

25SUGGEST

Not really an error, but be mindful of any other services you have listening on this port. Postgres.app uses 5432 as well. Node doesn’t throw an error if the port is in use.

25ERROR

In the code for the net-watcher.js file in the “watcher setup” section the code reads:
‘let watcher = fs.watch(filename, function(){
\t\t\tconnection.write("File ’" + filename + “’ changed: ” + Date.now() + “\
”);
\t\t}); ’

The problem arises when you listen for the change in the terminal, because “Date.now()” does not produce a humanly readable date, instead it produces the number of milliseconds since January 1, 1970. Therefore on the following page when an example of what should be output in the terminal is shown as “Sat Jan 12 2013 12:35:52 GMT ……” this is incorrect.
Please look into this.

30ERROR

When changing the code to the call of “connection.write” as suggested on page 30, the same error occurs when using the Date.now() object as was used on page 25.

So instead of having:

connection.write(JSON.stringify ({
type: ‘changed’,
file: ‘filename’,
timestamp: Date.now()
}) + ‘\
’ );

Which will replace the date in milliseconds since Jan1, 1970,
We should write:

connection.write(JSON.stringify ({
type: ‘changed’,
file: ‘filename’,
timestamp: new Date()
}) + ‘\
’ );

Thanks,

89SUGGEST

Error: Most middleware (like logger) is no longer bundled with Express and must be installed separately.
I got this error with the newer version of Express (4.4.5). The cure is simple:

- >npm install —save morgan (in cli)

- add new constant to the server.js
logger = require(‘morgan’),
- modify ‘middleware’ line in server.js (note, logger is no more part of Express):
app.use(logger(‘dev’));

Check ‘connect’ repo on github, section middleware for more information.

98ppERROR

Instead of " … as a successful resolution of the promise and calls the second then’s handler function…" it should read: " … as a successful resolution of the second promise and calls the second then’s handler function…"

Also at the end of the next paragraph instead of “…, then uses its value to resolve the original promise,…” it should read “…, then uses its value to resolve the second promise…”.

Instead of second also next could be used.

16SUGGEST

(Loc 172 in Kindle) As an FYI (knowing that you can’t account for all *nix distros), on Ubuntu 14.04 node is named ‘nodejs’ the shebang is “#!/usr/bin/nodejs —harmony”.

1SUGGEST

the book is great, thank you.
i want to note something here about all the code you wrote in the book. as developer that come from other languages and as someone that push other to write cleaner code, meaning, small functions that show “one idea” and not whole code section that compose from tons of anonymous functions.
the JS problem today is the spaghetti developer doing from their code. and i think that good book that want to teach the “right way” need to show also, from his examples, how to write it well and structured.
this issue is all over this book.

thank you again on that book,
Nisim

130ERROR

most of express modules are not inside the Express module anymore. you have those in external modules.
you need to set a comment about it because most of the examples are not working in express 4.x.

1491ERROR

zmq-filer-rep-cluster.js, uses .bind(‘ipc://filer-dealer.ipc’); This does not work on my Ubuntu 14.04 (launched using Vagrant). This has to do with permissions or the URL, not sure which. When I changed it to ‘ipc:///tmp/filer-dealer.ipc’, it worked. I tried without three slashes (//tmp instead of ///tmp) but that fails. If I don’t put it in tmp and use ///filer-dealer.ipc, then I must launch node with sudo. The one common thread though is that it seems to need three slashes before the name.

1869ERROR

The selector for subjects to not take into account that the rdf:value elements may be before or after the rdf:resource element. The “~” only gets the “next sibbling”. The book used in the test has two subjects, one is before, and the other is after, thus the code only retrieves the “after” one. The following selector seems to work and return both of the subjects:

subjects: $(‘[rdf\\\\:resource$=“/LCSH”]’).siblings(‘rdf\\\\:value’).map(collect).toArray()

1SUGGEST

In the files that were setup to be executable (using chmod), the shebang line #!/usr/bin/env node —harmony is likely to work only on a Mac. It appears that adding parameters such as “—harmony” is not possible under most distros of Linux. It might be more universal to execute all node scripts using the node command, or at least explain that it is not user error when the —harmony flag causes a “No such file or directory error”.

72ERROR

In addition to enabling xmlMode mentioned in #76602, add the method .get() for both authors and subjects

authors: $(‘pgterms\\\\:agent pgterms\\\\:name’).map(collect).get(),
subjects: $(‘[rdf\\\\:resource$=“/LCSH”] ~ rdf\\\\:value’).map(collect).get()

Test with cheerio 0.18.0

116ERROR

Using latest connect-redis, redis, express 3.3.8 and nodemon I was not able to produce the REDIS ECONNREFUSED error when killing the redis server using ctrl+c or ctrl+z.

I can confirm that redis is working, as the hello-world examples on pp109-116 worked as intended.

18ERROR

In read-stream.js the ‘data’ event handler needs to be added AFTER the ‘error’ event handler - currently adding the ‘data’ event handler will switch the ‘Readable Stream’ from paused mode to flowing mode before the ‘error’ event handler has been added (so the specified error handler will not be executed when ‘flowing mode’ immediately runs into problems like when the file does not exist).

See Node.js Manual & Documentation Class: stream.Readable

72ERROR

In pg132.json, authors should be:

“authors”: [
“Giles, Lionel”,
“Sunzi, active 6th century B.C.”
],

This matches the text and order of the latest version of the database from Project Guttenberg

15SUGGEST

Jim, I’m enjoying your book. I find your writing style easy to follow. So thanks.

Being new to Node, it took some digging to find valid events to listen for in the first place.

For example, ls.stdout.on(‘what can go in here?’,…

After reviewing nodejs docs, I figured it out. However, it might help other readers to clarify how to find a list of valid events to listen for.

80ERROR

When using the dbcli program from the command line to delete a document, you may need to encase the URL argument in quotes-

./dbcli.js DELETE books/0?rev=1-453265faaa77a714d46bd72f62326186

…will not work, but this will:

./dbcli.js DELETE ‘books/0?rev=1-453265faaa77a714d46bd72f62326186’

18SUGGEST

You can make executable node.js scripts on linux for example:

#!/home/jda2000/.nvm/versions/node/v4.1.0/bin/node —harmony
“use strict”;
let i = “j”;
console.log(‘[’ + process.argv[0] + ‘]’);
console.log(‘[’ + process.argv[1] + ‘]’);
console.log(‘[’ + process.argv[2] + ‘]’);
require(‘fs’).createReadStream(process.argv[2]).pipe(process.stdout);

Obviously, the —harmony option “took” and the file name argument is where it needs to be.

You might mention this.

27SUGGEST

It seems on Ubuntu 14.04 you have to use Ctrl]quit to exit telnet Ctrl]Ctrl-C seems to be ignored.

1864SUGGEST

To finally get the nodeunit test working in the section titled: “Unit Testing with Nodeunit” I needed to have this callback in rdf-parser.js.

I also needed to change the author text in pg132.json to:
“Sunzi, active 6th century B.C.”

I also needed to run the test with (minus the node —harmony):
$(which nodeunit) test/

callback(null, {
_id: $(‘pgterms\\\\:ebook’).attr(‘rdf:about’).replace(‘ebooks/’, ’‘),
title: $(’dcterms\\\\:title’).text(),
authors: $(‘pgterms\\\\:agent pgterms\\\\:name’).map(collect).get(),
subjects: $(‘[rdf\\\\:resource$=“/LCSH”]’).siblings(‘rdf\\\\:value’).map(collect).get()
});

2372ERROR

At the start of chapter six, when creating the hello server. Before installing express, run “npm init” and just press Enter when prompted multiple times, to create a default package.json file. Then add this before the closing curly brace:

“dependencies”: {
“express”: “~3.3.5”
}

Then do “npm install”

If you don’t have this and just do “npm install —save express” you will likely get the wrong version of express, and when you try to start the server will likely get errors. These are the errors I got:

c:\\xampp553\\htdocs\\myStudy\\javascript\
odejs\\myNodeTheRightWayFiles\\chapterSix\\hello\
ode_modules\\express\\lib\\express.js:99
throw new Error(‘Most middleware (like ’ + name + ’) is no longer bundled with Express and must be installed separately. ^

Error: Most middleware (like logger) is no longer bundled with Express and must be installed separately.
at Function.Object.defineProperty.get (c:\\xampp553\\htdocs\\myStudy\\javascript\
odejs\\myNodeTheRightWayFiles\\chapterSix\\hello\
ode_modules\\express\\l
ib\\express.js:99:13)
at Object. (c:\\xampp553\\htdocs\\myStudy\\javascript\
odejs\\myNodeTheRightWayFiles\\chapterSix\\hello\\server.js:6:16)
at Module._compile (module.js:398:26)
at Object.Module._extensions..js (module.js:405:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Function.Module.runMain (module.js:430:10)
at startup (node.js:141:18)
at node.js:980:3

npm ERR! Windows_NT 6.3.9600
npm ERR! argv “c:\\\
odejs\\\
ode.exe” “c:\\\
odejs\\\
ode_modules\\\
pm\\\\bin\\\
pm-cli.js” “start”
npm ERR! node v5.3.0
npm ERR! npm v3.3.12
npm ERR! code ELIFECYCLE
npm ERR! hello@1.0.0 start: `node server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the hello@1.0.0 start script ‘node server.js’.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the hello package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node server.js
npm ERR! You can get their info via:
npm ERR! npm owner ls hello
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! c:\\xampp553\\htdocs\\myStudy\\javascript\
odejs\\myNodeTheRightWayFiles\\chapterSix\\hello\
pm-debug.log

2436ERROR

When you start working on the b4 app in chapter 6, make sure you CD into the b4 directory and run npm install again, to get dependencies. The book doesn’t explicitly tell you to do that.

110ERROR

From the downloaded files, I am able to install and run redis-server, able to start server.js using npm start, start the couchdb (which was a major pain to get proper permissions on my linux mint rosa setup), when I run the curl to see the HEAD of /api/test I get

HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Type: text/plain
Set-Cookie: connect.sid=s%3Aj_kSaqNS7GOlkkj9YjY0HZy5.ccozcgvRIRLihZij868T9jX4JNwuNLF3VQ%2BWbuTwtZE; Path=/; HttpOnly
Date: Thu, 28 Apr 2016 23:50:56 GMT
Connection: keep-alive

Being new to node, I have no idea what is being not found and how to debug what it might be. Any help would be great.

51ERROR

In running the loop version of the zqm-filer script, I’m issuing three requests in the loop, as per instructions, but only getting one response.

In the terminal running the rep script (zmq-filer-rep.js) it’s only showing that one message came in. Any ideas why this would be? Am I doing something wrong? The code looks the same as the book.

72ERROR

In addition to adding .get() for both subjects and authors as mentioned in #76602 (which in turn mentions enabling xmlMode in #76602, which I also used), I needed to modify the selector to find all the subjects as the ‘~’ selector finds next siblings and ignores any previous siblings, and the version of the rdf data I obtained had one rdf\\\\value element after the LCSH element, and one before. I used the following to find both subjects : subjects: $(‘[rdf\\\\:resource$=“/LCSH”]’).siblings(‘rdf\\\\:value’).map(collect).get()

72SUGGEST

no footnote for cheerio?

you have footnotes on many less significant topics, but nothing for cheerio!

ch04ERROR

in the zmq-filer-rep-cluster.js program:

in both the router.on() and dealer.on() calls, the Array.prototype.slice.call() methods are shown with the first one with just one argument:
Array.prototype.slice.call(arguments);

… and the second one with 2 arguments to call
Array.prototype.slice.call(null, arguments); // this is what is shown earlier in the text.

The program worked perfectly for me only when both the router() and dealer() used the 1-arg version.

Categories: