By Developers, For Developers

Historical errata for Reactive Programming with RxJS

PDF PgPaper PgTypeDescriptionFixed onComments
4TYPO

Section: Querying the Sequence
In thinking_sequences1.js, the event listener is added for the ‘mousemove’ event, but the text talks about handling ‘mouseclick’ events.

2015-09-24
viSUGGEST

In the .epub version of the book, any bulletted list items have an extremely small line spacing that makes the text almost unreadable. If it helps, I’m using Aldiko Reader on a Nexus 5.

45ERROR

In code1_2.js, the identifier ‘dataset.features’ needs to be replaced by ‘dataset.response.features’

2015-09-24
50ERROR

First off, the book is fantastic so far! I was hoping to try out the spaceship game, but it appears rx.all.js is missing from the demo folder. I went to rxjs’ github page and download version 3.1 (used link from the bottom of preface X). When I ran the page again game.subscribe() ultimately threw this error twice:
Uncaught TypeError: fn must be a functiontryCatch @ rx.all.js:66InnerObserver.onNext @ rx.all.js:4567tryCatcher @ rx.all.js:59AutoDetachObserverPrototype.next @ rx.all.js:10055Rx.internals.AbstractObserver.AbstractObserver.onNext @ rx.all.js:1711(anonymous function) @ rx.all.js:8610(anonymous function) @ rx.all.js:1174

2015-09-26
6ERROR

on the left side of the screen => on the right side of the screen

2015-10-08
13ERROR

Rx.Observable
.from([‘Adrià’, ‘Jen’, ‘Sergi’])
.subscribe(
function(x) { console.log(‘Next: ’ + x); },
* argument for error is missing
=> ‘Completed’ is not logged
=> insert here “null,” and ‘Completed’ appears
function() { console.log(‘Completed’); }
);

2015-09-25
14TYPO

‘mouseove’ => ‘mouseover’

2015-09-26
39TYPO

At the bottom of the page, the output doesn’t match the logging in associated code listing.

2015-09-27
53SUGGEST

When moving the star, you can set star.y += star.size to make a neat parallaxing effect ;-)

2015-10-14
58ERROR

It looks like throttleFirst is missing from the Observable prototype in RxJS v3.1.2. “throttle” works.

2015-09-26
33ERROR

Thank you for the book! It has been a great read.

2 suggests for the section ‘There is Always a Method’:

(1) RxJS-DOM is not included in rx.all.js; if the text could mention including the rx.dom.js file in the main JS file could help;

(2) I’m new to RxJS and not sure about the flatMap function (dataset) - when I follow the text I got error ‘iterable cannot be null.’ After some debugging, changing Rx.Observable.from from dataset.features to dataset.response.features fixes the bug as the whole response object got wrapped when passed to the flatpMap function. Currently I am using RxJS-DOM 6.0 and RxJS 4.0.

2015-10-14
44TYPO

Small typo on code1_1.js

return Rx.Observable.from(dataset.response.features);

Thoroughly enjoying the read!

2015-10-14
59ERROR

Scan function in hero_shots.js takes an empty array as the first argument when it should be the second…

2015-10-08
12TYPO

In the onerror function, ‘Observer’ should be ‘observer’, and “Error(” possibly “new Error(”.

req.onerror = function() { Observer.onError(Error(“Unknown Error”));

2015-10-08
98TYPO

[just couldn’t let this one go unnoticed :-]

First bullet para after heading Testing with Schedulers :

. . is to avoid bugs an errors.

2015-10-14
14ERROR

For the `Rx.fromArray` example, a null is needed for the second parameter for the onCompleted call to be correct:

```
Rx.Observable.from([ `Adria`, `Jen`, `Sergi` ])
.subscribe( (x)=> console.log( `Next: ${x}` ), null, ()=> console.log( `Completed` ) );
```

2015-11-08
19TYPO

More grammar/expression than a typo:
RxJS follows JavaScript conventions, so you will find that the syntax for the following is almost the same [than for] array operators.

I would write [as that of] or similar.

2015-11-08
36TYPO

“Here’s what’s happening:
. . .
(3) . . . from that function in the source Observable.”

Should that say

“(3) . . . from that function into the source Observable.”

2015-11-08
15ERROR

on page 15, “creating observables from callback functions”, the node fs library function we’re observing is ‘readdir’. readdir technically returns two elements: an error, and the file list.
see: nodejs.org/api/fs.html#fs_fs_readdir_path_callback

on the line that’s logging the list of directories:
console.log(‘List of directories: ’ + res)
res is an array containing both arguments: the error, and the list of files. so if you look closely, the stringified output always starts with a null (i assume because there’s no error).
so perhaps it would be more correct if that code line read: console.log(‘List of directories: ’ + res[1])

anyways, it’s really minor, but it tripped me up. my natural reaction was to extend the example to observe the list of files and filter out perhaps hidden files (ones that start with a ‘.’). when i did this i kept getting an npe on the error argument, and I couldn’t understand why my Observable.from(response) was not emitting one event per file. the solution of course was to do Observable.from(response[1])

thanks. so far the book is a great read!

2015-11-09
53ERROR

the first improvement to the implementation uses flatMap. as far as i can tell, the observable we create emits the response, and the argument to the function argument of flatMap should likewise be ‘response’. instead it’s ‘dataset’. i believe this is in error.

2015-11-09
61ERROR

bottom of page “the output is now the following:”..
output does not correspond to code example: the code suggests output that looks like this:
Subscriber 1 - distance: x pixels
while the output shows:
Click Subscriber" { x: .. y: .. } 1
clearly this output is from running a different code sample.

2015-11-09
62ERROR

discrepancy between output and code: output suggests clickInfo is an object with properties x, y, and count. yet the code clearly shows clickInfo is designed with x, y, lastX, and lastY. i don’t see how lastX and lastY transform into some sort of click count.

separately, perhaps a suggestion: some readers may not yet have internalized the scan operator so it may be worth repeating in the narrative that you’re basically doing some kind of reduce or accumulation.

2015-11-09
7557ERROR

the .toArray() invocation follows a semicolon in starfield_1.js; this will throw an error.
i suppose it needs to read “StarStream.toArray()…”

2015-11-08
12TYPO

req.onerror = function() {
Observer.onError(Error(“Unknown Error”));
};

Observer needs to be observer.

2015-11-08
8163SUGGEST

it appears that, in chrome at least, the canvas never gets the focus and so the spacebar keyboard events never fire.

this thread discusses a solution by giving the canvas a tabindex:
stackoverflow.com/questions/56771/how-do-you-set-focus-to-the-html5-canvas-element/57332#57332

2015-11-09
24TYPO

Now it is: “Create an Observable of click events and filter out the clicks that happen on the left side of the screen.”

It should be “Create an Observable of click events and filter out the clicks that happen on the right side of the screen.”

2015-11-08
33ERROR

For reading directory, the code example is not complete. First of all as this is Node example, it lacks requiring rx:

var rx = require(‘rx’);

Then in line 2:
var readdir$ = rx.Observable.fromNodeCallback(fs.readdir);

We should use fromNodeCallback instead of fromCallback, as readdir is callback function in Node format (error, …). Using fromCallback when success gives as null as first argument which makes no sense.

2015-11-09
83ERROR

On page 83 you point out the “just” identity function being part of helpers but from RxJs 2 and up just is part of Observable.

So this is correct Rx.Observable.just and not Rx.helpers.just.

Regards,

Slan

2015-11-08
80TYPO

There is an error in event attribute name. Is should be evt.keyCode, not evt.keycode. Moreover, keyCode is now deprecated and keyIdentifier or key should be used instead.

2016-03-31
43TYPO

Near bottom of page:

‘The output is now the following:’

The given output is wrong for the code above it.

2016-04-04
1515ERROR

Rx.Observable.fromCallback returns an observable for the first argument passed into the callback. In the case of readDir, that is reserved for the error object if one exists. Thus, the observable sequence would emit null. What should be used is rx.Observable.fromNodeCallback. I’d link to the docs but the spam filter won’t allow hyperlinks…

2015-11-25
43ERROR

At the end of the page, the program output does not correspond to the program code. After that, in page 44, the example is discussed but this mismatch between the output and the code makes the explanation wrong too.

2016-04-04
44TYPO

In the example of page 44, at the end it’s mentioned that .map passes an index parameter, when we the example is not using .map but .scan

2016-04-04
52ERROR

argument should be `dataset.features` instead of `dataset.response.features`

in the

.flatMap(function transform(dataset) {
return Rx.Observable.from(dataset.response.features);
})

2016-04-04
13ERROR

The body copy references the `Rx.DOM.Request.get` method, however the example uses `Rx.DOM.get`. The body copy is erroneous as the `Request` object does not exist within `Rx.DOM`.

2016-03-31
33ERROR

In the code “examples_earthquake/code1_1.js“:
`return Rx.Observable.from(dataset.response.features);`
should be
`return Rx.Observable.from(dataset.features);`

2016-03-30
37ERROR

first returned value is 2 ie 1 * 2 = 2 not 1

Where is the code you are referring to? I can't find it on page 37
33ERROR

In the code given:

var quakes = Rx.Observable.create(function(observer) {
window.eqfeed_callback = function(response) {
❶ observer.onNext(response);
❷ observer.onCompleted();
};
loadJSONP(QUAKE_URL);
❸ }).flatMap(function transform(dataset) {
❹ return Rx.Observable.from(dataset.response.features);
});

this doesn’t work.. the ‘response’ is what is given to the observer, but the flatMap operator tries to make an observable out of the dataset.response.features, but this doesnt exist — it should be dataset.features..

2016-03-30
20TYPO

In the book:
var isEven = (function(val) { return val % 2 !== 0; });

Expected:
var isEven = (function(val) { return val % 2 == 0; });

2016-03-30
4TYPO

document.body.addEventListener(‘mousemove’, … should be
document.addEventListener(‘click’,
to be consistent with the first 10 clicks example that is supposed to “change the preceding code”

2016-03-30
13TYPO

In the code example at the bottom of the page there should be a comma between the error function and the completion function.

2016-03-30
4TYPO

snippet from “ch1/thinking_sequences1.js” has ‘mousemove’ event, even though the text describes ‘click’ event:
(document.body.addEventListener(‘mousemove’, function(e) {)

It should be:

document.body.addEventListener(‘click’, function(e) {

2016-03-30
54SUGGEST

The calculating of the star movement can be improved by moving bigger stars faster, thus creating a more real-like parallax effect.

I have changed:

`star.y += 3; // Move star`

to

`star.y += star.size; // Move star`

2016-04-20
96ERROR

Using the `animationLoop()` function as shown in the snippet make the page unresponsive and there is an infinite loop going into `starArray.forEach()`,

The page shows nothing, just hangs the browser.

Also, why is there `scheduler` set as a `animationLoop(scheduler)` parameter if it is not used?

2016-03-31
67ERROR

The final version if game doesn’t work. I can only see blank screen, even clicking on it. There is no error in the developer console. The problem starts because of adding score stream. I changed the code slightly. Instead of using Subject and contact for score stream, I used BehaviorSubject.

Moreover, in the source code, the score stream is added as a parameter to combineLatest. However, it is not added as a last parameter of the function in combineLatest:

Rx.Observable.combineLatest(
StarStream, SpaceShip, Enemies, HeroShots, score,
function(stars, spaceship, enemies, heroShots) {

2016-03-31
57ERROR

At spaceship_reactive/pipeline.js,
Rx.Observable.from(1, 2, 3, 4, 5, 6, 7, 8)
should be
Rx.Observable.from([1, 2, 3, 4, 5, 6, 7, 8])

Otherwise, Observable.from() will throw an error says ‘mapFn when provided must be a function’. mapFn is the 2nd argument of the function.

2016-03-31
45TYPO

a source Observable that emits an integer every second.
should be
a source Observable that emits an integer every 300 milliseconds.

because the source code is following.
var source = Rx.Observable.interval(300)

2016-03-31
60ERROR

canvas does not receive keydown events as a default, at least on Firefox and Chrome.
So, it might be better to listen document or window.

Rx.Observable.fromEvent(document, ‘keydown’)

Or you could add tabIndex to canvas, then it will receive keyboard events while focused.

canvas.tabIndex = 1;

2016-03-31
61ERROR

After adding HeroShots to the Game Observable, the game is not started until a shot is fired.
I added .startWith([]) at the last of the HeroShots observable pipeline to avoid this issue.

var HeroShots = Rx.Observable
.combineLatest(
playerFiring,

.startWith([]);

2016-03-31
67ERROR

In order to add starting point to the score observable,
.concat(Rx.Observable.return(0));
should be
.startWith(0);

2016-03-31
72SUGGEST

It might be better to add some style change code here otherwise the quakes table won’t be displayed without scroll.
I changed #map height from 100% to 70%.

#map { height: 70%; }

2016-04-20
80TYPO

“In our previous example, we created three events for each row”
should be
“In our previous example, we created three events just for the first row.”

Probably it is to avoid performance issue but the sample code and the text are not in sync.

2016-04-20
86ERROR

The javascript `concat` method doesn’t change the subject, you need to reassign to `boundsArray`:

`boundsArray = boundsArray.concat(bounds);`

2016-03-30
42SUGGEST

“This way we don’t increment the count with every new subscriber.”

This statement is inaccurate and misleading. The updateDistance function is still executed as often with the scan operator as with the map operator - so the total number of “increments” is still the same. What has changed is that scan will supply each subscriber with its own count instance
(which isn’t shared as it was in the first external state example).

function updateDistance(acc, i) {
console.log(`- acc: ${acc} i: ${i}`);
if (i % 2 === 0) {
acc += 1;
}
console.log(`- acc: ${acc}`);
return acc;
}

- acc: 0 i: 0

- acc: 1
Subscriber 1 - evenTicks: 1 so far

- acc: 0 i: 0

- acc: 1
Subscriber 2 - evenTicks: 1 so far

- acc: 1 i: 1

- acc: 1
Subscriber 1 - evenTicks: 1 so far

- acc: 1 i: 1

- acc: 1
Subscriber 2 - evenTicks: 1 so far

- acc: 1 i: 2

- acc: 2
Subscriber 1 - evenTicks: 2 so far

- acc: 1 i: 2

- acc: 2
Subscriber 2 - evenTicks: 2 so far

- acc: 2 i: 3

- acc: 2
Subscriber 1 - evenTicks: 2 so far

- acc: 2 i: 3

- acc: 2
Subscriber 2 - evenTicks: 2 so far

- acc: 2 i: 4

- acc: 3
Subscriber 1 - evenTicks: 3 so far

- acc: 2 i: 4
- acc: 3
Subscriber 2 - evenTicks: 3 so far

For the original statement to be true an intermediate observable for publishing the result is required, typically via .publish().refCount() or .share():

var ticksObservable = Rx.Observable
.interval(1000)
.scan(updateDistance, 0) // original “cold” observable
.share(); // intermediate “hot” observable

- acc: 0 i: 0

- acc: 1
Subscriber 1 - evenTicks: 1 so far
Subscriber 2 - evenTicks: 1 so far

- acc: 1 i: 1

- acc: 1
Subscriber 1 - evenTicks: 1 so far
Subscriber 2 - evenTicks: 1 so far

- acc: 1 i: 2

- acc: 2
Subscriber 1 - evenTicks: 2 so far
Subscriber 2 - evenTicks: 2 so far

- acc: 2 i: 3

- acc: 2
Subscriber 1 - evenTicks: 2 so far
Subscriber 2 - evenTicks: 2 so far

- acc: 2 i: 4
- acc: 3
Subscriber 1 - evenTicks: 3 so far
Subscriber 2 - evenTicks: 3 so far

However .share() isn’t discussed until p.76 (Chapter 4).

2016-03-31
108ERROR

While updating the score, concat method was not working with scan method and Rx.Observable.return. It looks like concat method only works when the previous sequence is complete. So I had to use startWith to update the score.

2016-04-20
4ERROR

The initial example says “To log the x-and y coordinates of mouse clicks we could write something like this”

The code says

document.body.addEventListener(‘mousemove’

Which of course will log mouse moves.

20SUGGEST

It shuld be made clear that the value produced by reduce is emitted only when the source sequence completes. I found this picture here more accurate:

http //reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-reduce

96ERROR

The animation loop code seems to include an unintended code change from:
star.y += star.size;
to:
star.y += 3;

112SUGGEST

Perhaps add a note about the cycle.js author’s name: “Staltz is just a nickname I use on the web since 2004. My real name is André Medeiros, but I try to avoid it because it’s disappointingly unoriginal.” Staltz.com

62ERROR

Hi, I use latest release Rx (5.1.1).

Original (HeroShots implementation): “.distinctUntilChanged(function(shot) { return shot.timestamp; })”

but now, you need write like this: “.distinctUntilChanged(function(prevShot, nextShot) { return prevShot.timestamp === nextShot.timestamp; })”

Categories: