How I use MobX 2 in an AngularJS 1 application

How I use MobX 2 in an AngularJS 1 application

MobX is a library simplifying state management by using functional reactive principles.
It manages dependencies between values, somehow like a spreadsheet does with its cells: if the value of a cell changes, other cells depending on the first one can change too, in a cascading way.

The manual of MobX can be read at MobX, Simple, scalable state management.
It is a comprehensive guide, rather dense (worth reading again after experimenting with the library…) but clear and informative.

I used it in an AngularJS 1 application, to manage state of controllers (components), so in a rather local and isolated way.
That’s just one way of using it, which I explain below.


Read more

MessagEase (Android keyboard) review

MessagEase (Android keyboard) review

MessagEase keyboard

Most Android keyboards suffer from the same flaw: they mimic traditional typewriter / computer keyboards.
The (only?) advantage is that most users are familiar with it.
The inconveniences are numerous:

  • These keyboards were designed to slow down typing… (well, multi-finger typing, but still, they are not intuitive).
  • People are trained / used to type with several fingers, while on Android you are limited to two, at best.
  • These keyboards often lack arrow keys, Delete key and multi-key / finger combinations, like shifting to capital, Ctrl+C / Ctrl+V, Ctrl+Backspace to delete a word, etc. To reach some keys (accented chars) and go back to regular typing, you might have to type three or four keys.
  • Keys are small, particularly on small phones.

I thought of a squarish / circular design around a central point, where letters surrounding it would change to make more accessible the letters more likely to follow the previous ones (for a given dictionary).
Idea with a number of caveats, like not relying on muscle memory and needing to know the context in the edited text.

So I searched alternatives (they are numerous!), tried some (disliked swipe-based ones, liked Hacker’s Keyboard in its classical category) and finally stumbled upon MessagEase.
I felt it was the right one, even if I expected some learning curve… It was close of my idea, but with a fixed layout (for a given language), and it makes the most common letters easier to type than the rarest ones.

Its square design make it look huge, but in practice, with its 4x4 keys, it is not much bigger than a four row traditional keyboard. And you can easily adjust its size to fit your taste / capabilities.
It is very flexible, with tons of settings to adjust finely the look and feel of the keyboard, to adapt it to the needs and tastes of the users. Yet, it has sensible defaults, so it is good out of the box.

Read more

GitHub Atom review

GitHub Atom review

“A hackable text editor for the 21st Century”



I came to Atom with a prejudice…
The long closed-source / beta period, the fact the “hackable” editor isn’t coded in JavaScript but in CoffeeScript, the need to add plugins for everything (according to some reviews), the reported slowness and memory hungriness, made me to hesitate to try it… I was also a happy user of Adobe Brackets, with no compelling need to change.
But, Brackets accumulated a number of little annoyances, making me wanting to try other editors.
The test of Visual Studio Code was brief, as it didn’t have the base (semi-advanced if you want) features I use all the time: drag’n’drop of code, and column selection.
So I tested Atom, with a critical eye. Spoiler: I was seduced, and it becomes my favorite Web IDE…

That’s the problem with information found on Internet: it quickly becomes stale…
The Atom team improved memory consumption, have an eye on responsiveness (I was impressed by their TimeCop package, and the fact they report for each package the time they add to loading), ship lot of plugins with the base editor: delegating to packages is part of their vision of modularity, but they made official packages for the most essential features, and you don’t need to hunt every package implementing base features, saving time.

I appreciate the clean interface and the attention to details they have bring to the project.

Read more

RxJS distributions

RxJS distributions


RxJS has several distributions:

  • The Core distribution, with two sub-modules, is a minimal implementation;
  • The Main distribution is broken down between a main module and several sub-modules;
  • The Lite distribution is similar to the Main one, but with different assignments: it includes a big part of the binding library, and part of the async one, so it is more usable without including other modules;
  • The All distribution includes nearly everything, as the name implies.

As this is a bit confusing, I made a table out of the official doc, including all mistakes found in this manually generated doc, some of which I point out here, to help tracking them down.

The distributions

Numbers are size in KB of .min.js as of 4.0.6 around October 2015. To be used only as comparison between versions.
The file names with + are not in the documentation, I found them after installing RxJS. I guess they come from v.4, and that the doc is still about v.3.

File name Id Size (KiB)
Complete library
rx.all.js A 139
Lite libraries
rx.lite.js L 81
rx.lite.aggregates.js LAg 17
rx.lite.async.js LAs 4
rx.lite.backpressure.js + 4
rx.lite.coincidence.js LCo 7
rx.lite.experimental.js LXp 8
rx.lite.extras.js LEx 10
rx.lite.joinpatterns.js LJp 5
rx.lite.testing.js LTe 7
rx.lite.time.js LTi 9
rx.lite.virtualtime.js LVt 4
Main library
rx.js R 72
rx.aggregates.js RAg 16
rx.async.js RAs (needs RBi) 7
rx.backpressure.js + 8
rx.binding.js RBi 7
rx.coincidence.js RCo 7
rx.experimental.js RXp 8
rx.joinpatterns.js RJp 5
rx.sorting.js + 3
rx.testing.js RTe (needs RVt) 7
rx.time.js RTi 16
rx.virtualtime.js RVt 4
Core library
rx.core.js C 15
rx.core.binding.js CBi 10
rx.core.testing.js CTe 14

Included Observable Operators

Observable Methods

Method name In All Library id for Lite Library id for Main Library id for Core
amb A LEx R
case A LXp RXp
catch A L R
concat A L R
create A L R C
defer A L R
empty A L R
for A LXp RXp
forkJoin A LXp RXp
from A L R
fromArray A L R
fromCallback A L RAs
fromEvent A L RAs
fromEventPattern A L RAs
fromNodeCallback A L RAs
fromPromise A L RAs (4)
generate A LEx R
generateWithAbsoluteTime A LTi RTi
generateWithRelativeTime A LTi RTi
if A LXp RXp
interval A L RTi
just A L R
merge A L R
mergeDelayError A L R
never A L R
of A L R
ofArrayChanges A
ofWithScheduler A L R
onErrorResumeNext A LEx R
pairs A L R
range A L R
repeat A L R
return A L R
spawn A LAs RAs
start A LAs RAs
startAsync A LAs RAs
throw A L R
timer A L RTi
toAsync A LAs RAs
toPromise RAs
using A LEx
when A LJp RJp
while A LXp RXp
wrap A RAs
zip A L R

Observable Instance Methods (prototype)

(! marks functions also on object)

Method name In All Library id for Lite Library id for Main Library id for Core
aggregate A LAg RAg
all A LAg RAg
amb ! A LEx R
and A LJp RJp
any A LAg RAg
asObservable A L R
average A LAg RAg
buffer A LCo RCo
bufferWithCount A LEx R
bufferWithTime A LTi RTi
bufferWithTimeOrCount A LTi RTi
catch ! A L R
combineLatest A L R
concat ! A L R
concatAll A R
concatMap A L R
connect A L RBi CBi
controlled A
count A LAg RAg
debounce A L RTi
defaultIfEmpty A L R
delay A L RTi
delaySubscription A LTi RTi
dematerialize A L
distinct A LEx R
distinctUntilChanged A L R
do A L R
doOnNext A L R
doOnError A L R
doOnCompleted A L R
doWhile A LXp RXp
elementAt A LAg RAg
every A LAg RAg
expand A LXp RXp
extend A LXp RXp
filter A L R
finally / ensure A L R
find A LAg RAg
findIndex A LAg RAg
first A LAg RAg
flatMap A L R
flatMapFirst A LXp RXp
flatMapLatest A L R
flatMapObserver A R
flatMapWithMaxConcurrent A LXp RXp
forkJoin ! A LXp RXp
groupBy A LCo RCo
groupByUntil A LCo RCo
groupJoin A LCo RCo
ignoreElements A L R
includes A LAg (5) RAg (3)
indexOf LAg RAg
isEmpty A LAg RAg
join A LCo RCo
last A LAg RAg
lastIndexOf A LAg RAg
let A LXp RXp
manySelect A LXp RXp
map A L R
max A LAg RAg
maxBy A LAg RAg
merge ! A L R
mergeAll A L R
min A LAg RAg
minBy A LAg RAg
multicast A L
observeOn A LEx R
onErrorResumeNext A LEx R
pairwise A LCo RCo
partition A LCo RCo
pausable A (L)
pausableBuffered A
pluck A
publish A L RBi CBi
publishLast A L RBi CBi
publishValue A L RBi CBi
refCount A L RBi CBi
reduce A LAg RAg
repeat A L R
replay A L RBi CBi
retry A L R
retryWhen A L R
sample A L & LTi RTi
scan A L R
select A L R
selectConcat A L R
selectMany A L R
selectManyObserver A
sequenceEqual A LAg RAg
selectSwitch L R
selectSwitchFirst LXp RXp
selectWithMaxConcurrent LXp RXp
share A (1) RBi CBi
shareLast RBi CBi
shareReplay A (1) RBi CBi
shareValue A (1) RBi CBi
single A LAg R & RAg
singleInstance A L RBi CBi
skip A L R
skipLast A L R
skipLastWithTime A LTi RTi
skipUntil A L R
skipUntilWithTime A
skipWhile A L R
slice A LAg RAg
some A LAg RAg
startWith A L R
subscribe / forEach A L R
subscribeOn A LEx R (2)
subscribeOnNext L R
subscribeOnError L R
subscribeOnCompleted L R
sum A LAg RAg
switch / switchLatest A L R
switchFirst A
take A L R
takeLast A L R
takeLastBuffer A LEx
takeLastBufferWithTime A LTi RTi
takeLastWithTime A LTi RTi
takeUntil A L R
takeUntilWithTime A
takeWhile A L R
tap A L
tapOnNext A L
tapOnError A L
tapOnCompleted A L
thenDo LJp RJp
throttle A L RTi
timeInterval A LTi RTi
timeout A L & LTi RTi
timeoutWithSelector LTi
timestamp A L & LTi RTi
toArray A L R
toMap LAg RAg
toPromise ? L
toSet LAg RAg
transduce L R
where A L R
window A LCo RCo
windowWithCount A LEx R
windowWithTime A LTi RTi
windowWithTimeOrCount A LTi RTi
withLatestFrom A L R
zip ! A L R
zipIterable A L R

Included Classes

Core Objects

Class name In All Library id for Lite Library id for Main Library id for Core
Rx.Observer A L R C
Rx.Observable R C
Rx.Notification A L R CTe


Class name In All Library id for Lite Library id for Main Library id for Core
Rx.AsyncSubject A L R CBi
Rx.BehaviorSubject L RBi CBi
Rx.ReplaySubject L RBi CBi
Rx.Subject A L R CBi


Class name In All Library id for Lite Library id for Main Library id for Core
Rx.Scheduler A L R C
Rx.TestScheduler LTe RTe CTe
Rx.VirtualTimeScheduler LVt RVt CTe
Rx.HistoricalScheduler LVt RVt


Class name In All Library id for Lite Library id for Main Library id for Core
Rx.CompositeDisposable A L R C
Rx.Disposable A L R C
Rx.RefCountDisposable A L R
Rx.SerialDisposable A L R C
Rx.SingleAssignmentDisposable A L R C

Testing classes

Class name In All Library id for Lite Library id for Main Library id for Core
Rx.ReactiveTest LTe RTe CTe
Rx.Recorded LTe RTe CTe
Rx.Subscription LTe RTe CTe
Rx.TestScheduler (see Schedulers above)

(XYz): not in the lists, but found in the description of the operator.
(1): Out of order in the list at
Also some methods / classes are not in All?
(2): Out of order in the list at
(3): Out of order in the list at
(4): Not in
(5): Out of order in the list at

Functional Reactive Programming

Functional Reactive Programming

FRP is a way to deal with events and asynchronous data in a functional style.
Basically, it is an implementation of the Observer design pattern, coupled with the Iterator one, dealing with streams of data coming on a timeline with a fluid API.


We saw, in the article about functional programming, powerful ways to process iterable data, by composing functions, with lazy evaluation able to deal with infinite data, etc.
FRP does the same, but applied to streams of events, which introduces a new dimension: time.
Events can be seen as some data coming at a given point in time.
Data might come from user interaction: a keyboard key is pressed or released, the mouse moves, is pressed, dragged, released, etc.
Data can also come from a server, after an asynchronous request. File system requests (asynchronous reading of file in Node.js, for example) are similar.
It can also be a timer, delivering a timeout once or regularly.
It can even come from static data (eg. content of an array): in this case, time is “now”.

Read more

Using Lodash for fun and profit

Using Lodash for fun and profit

Lodash is a JavaScript utility library enabling a functional programming coding style.
Lodash has general purpose functions, for type checking, string utilities, even functions to manipulate functions.
More importantly, it has functions to manipulate collections. Collections is a general term covering arrays, objects (seen as maps) and even strings (seen as arrays of characters).

This allows to replace most for loops with powerful and succinct function calls, showing clearly the intent of the operation without having to analyze complex code.


Read more

Adobe Brackets review

Adobe Brackets - IDE for the Web

Integrated Development Environment oriented toward the Web technologies


Quick review

I installed Brackets (v. 1.2 on Windows 7 with 8 GB of memory; currently at v.1.4), it went out quite smoothly, just asking for the directory where to install it.
I opened it, it starts very fast.
It has a dark UI but a light editing area. Not fan of dark theme, but I will try and keep it to see if it is effective to have a contrast between the UI and the editing area.
Default syntax coloring theme looks OK so far. It can be changed with theme plugins.
Actually, the UI theme cannot be changed easily, it needs a plugin to be able to modify it.
There is no drag’n’drop of text by default, which is why I rejected this editor on my first try (before 1.0), because I use this operation a lot; but it has been introduced in this version, and the blog post about this release shows how to activate it.
The editor is a bit primitive out of the box. You have to install several extensions to get things done efficiently… That’s OK because this keeps the application streamlined: no need to install CoffeeScript or Less extensions if you code only in JavaScript and use Sass…
There are not much settings either: you have to edit Json files to customize things. A bit less intuitive, but I am OK with that, as that’s the way I customize ScITE, my favorite (general purpose) source code editor. And not having complex dialogs to set every option also keeps the application light.

After a few weeks of using Brackets, I appreciate it a lot: it is much less memory hungry than WebStorm or Eclipse, it is flexible and easy to use.
I recommend it.

Read more