React is not just the V in MVC

It seems a lot of people like to say React is just the V in MVC. Even Facebook focus on this as the first comment on the React home page, "Lots of people use React as the V in MVC".

Dan Abromov (now working at Facebook on React) from "You’re Missing the Point of React"

At the time, downplaying React’s role in application architecture was intentional because React already had too many “seemingly bad” ideas to risk alienating people by adding some more.

And linking to this discussion where Christopher Chedeau (also known online as Vjeux and a Facebook employee working on React)

React architecture is based on components that, as you say, can take the role of Views and Controllers. But instead of having a clear separation between those two concepts, they are blended together. Leaf components are going to be mostly views, and as you go up the hierarchy they are going to look more and more like controllers. The hard separation appears on the component boundaries and not between V and C.

and

Since we want people to try it out, we downplayed the C important in our marketing talks. We are already challenging the idea of templates, we can't fight all the fronts at once

Unfortunately this seems to have caused some confusion and I've seen people dismiss React or talk about it without understanding React because of this.

Cycle.js FAQ

Some Cycle.js FAQ notes I threw together and will try rearrange that might help people using Cycle.js. Some of these are notes copied from the Cycle.js Gitter channel.

Why does Cycle.js code often have $ symbols in variables

The $ convention is used to signify a variable that is an Observable.

Another not so standard idea is to import Observable as another name like $, eg

1
import { Observable as $ } from 'rx';

Debugging Cycle.js

  • How to debug RxJS code
  • Adding a debugger; line to your code can be useful to break into your browser debug mode.
  • Logging RxJS (see below)

Logging for RxJS

1
2
3
var foo$ = bar$
.map(……..)
.do(x => console.log('foo$ emits ' + x));

or a prototype from @milankinen's gist

1
2
3
4
5
Rx.Observable.prototype.log = function(prefix) {
return process.env.NODE_ENV !== "development" ? this : this
.doOnCompleted(() => console.log(prefix, "<completed>")) // eslint-disable-line
.do(x => console.log(prefix, x)) // eslint-disable-line
}

Cycle.js Templating System

Cycle.js recommends using HyperScript Helpers, which I also prefer. There is also plain HyperScript and the React JSX support.

HyperScript and HyperScript Helpers

Hyperscript plain and Hyperscript helper conversion from HTML http://html-to-hyperscript.paqmind.com/

State

Redux concept in RxJS:

1
2
3
4
5
function store(action$) {
return makeReducerStream(action$)
.scan((state, reducer) => reducer(state), initialState)
.shareReplay(1);
}

What is Transposition in Cycle.js

@staltz Transposition is: a child of a vdom element can be an Observable<VElement> and at the end it will be flattened as one "video".

Combinators in this article are the same concept.

Isolate, Children and Events

A really cool example by @laszlokorte on how events and isolation work with surrounding discussion on the TSERS Gitter channel.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Foo() {
return {
DOM: O.just(h("button.foo", "..."))
}
}

function Bar(sources) {
const click$ = DOM.select(".foo").events("click")
const click2$ = DOM.select(".bar").events("click")

const foo = isolate(Foo, "f1")(sources)
const vdom$ = foo.DOM.map((foo) => div('.bar',[
foo,
]))
return {
DOM: vdom$
}
}

click2$ will see the event that happens when the user clicks button.foo

Input Forms in Cycle.js

Here are some example repos with ideas on how to make input forms:

How go listen for keypress events on the whole app

Normally you listen to global keypresses with a driver as @TylorS explains here:

1
2
3
Cycle.run(main, {
keypress$: () => Rx.Observable.fromEvent(document, 'keypress')
})

The reason DOM.select() doesn't select from document, is because it's external to your main(). Drivers are the place where you listen to what is external to your main().

TypeScript Duplicate Identifier and Typings

If your TypeScript tsconfig.json is using "exclude" and Typings for your TypeScript definitions, you may run into duplicate identifier warning messages.

error TS2300: Duplicate identifier

This warning means you are probably including multiply copies of the same file, or a file is redefining the same definitions.

Typings currently creates definitions for 'main' and 'browser'. For a front-end package Typings suggests you are going to want the 'browser' types as they have browser field overrides. There was also an issue to remove creation of both browser and main versions, but currently a desired alternative has not been implemented.

Due to a lack of file globbing support, I tried changing to using "exclude" in my tsconfig.json. This means I don't individually list each item under "files", but every TypeScript file is included, apart from those files and directories I explicitly "exclude".

Soon after I noticed I was getting the duplicate identifier issues. Turns out the solution was already on the home page.

I found a similar question about duplicate identifiers here, so I added my own answer.

Basically you need to exclude the files you don't want to use from the Typings directory, eg:

{
  "exclude": [
    "typings/browser.d.ts",
    "typings/browser",
    "node_modules"
  ]
}

npm linked modules with webpack

I was was having some problems with an npm module that was not updated on the "master" branch. It also had a lot of dependent child libs. There was a "develop" branch that I wanted to try. For some reason I had an issue with trying to use the "develop" branch from npm.

npm install user/project#branch

I probably should have open a Stack Overflow question about it, but maybe later.

I ended up going a different route and using npm link and cloning a copy of the library.

I am trying to use WebPack, which seems like black magic... like a lot of the node ecosystem if you ask me.

Anyway, the code was still not compiling and could not find some of these dependent modules. Turns out this was not WebPack's fault, but another pain point I have found when using npm link.

The WebPack documentation has a description of the problem in their troubleshooting guide to get WebPack to find the dependencies of npm linked modules.

http://webpack.github.io/docs/troubleshooting.html#npm-linked-modules-doesn-t-find-their-dependencies

StrongLoop Reddit Vote Manipulation

Wow, I found this Reddit thread the other day where StrongLoop seem to admit to vote manipulation on Reddit.

Vote manipulation. Suddenly, spam accounts everywhere submitting strongloop, commenting favorably just on strongloop posts, etc. Really obvious pattern. Proof is easily found by looking at the domain search for strongloop, and by submitting anything pointing to the domain. Immediate spam queue - the domain is reddit-shadowbanned.

reply by jakerella

Hi there, I'm a DE for StrongLoop. Yes, there was some tomfoolery going on previously, and I've specifically pushed for that to stop. Lately (last few months at least) you won't see that. That said, when other people post SL stuff we do pile on, but it's our staff voting up those posts, and we encourage them to be active members of the community at large. Again, not trying to excuse previous behavior, but trying to show that we're working to be better.

Exception Handling - Promises vs Observables

A friend of mine was studying Promises in JavaScript. I mentioned how Promises swallow exceptions and continue execution by default.

I have recently been following RxJS and decided to knock up an example to find out how exceptions are handled differently in Promises versus Observables.

In the JS Bin below you will find the Promise swallows the exception thrown and we continue onto the Observable.

When subscribed to, the Observable throws an exception and the execution is halted. We never reach the last console log.

If you use the commented out catch statement for the Observable, then we can run to the last console log and exit cleanly.

So if you are going to use Promises, make sure you are vigilant and don't let those errors slip through and bite you later on. Perhaps look into libraries like Bluebird that provide methods like onPossiblyUnhandledRejection to help you out. Or get on the Observables train ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var promise = new Promise((resolve) => {
console.log('running promise');
console.log('about to throw exception in promise');
throw "Error Promise";
});

promise.then( x => console.log(x));
console.log('NOTE: promise swallows exception and continues');

var source = Rx.Observable.create((observer) => {
console.log('running observable');
console.log('about to throw exception in observable');
throw "Error Observable";
observer.onNext('observable onNext');

// uncomment below to catch observable exception
// }).catch(function(e){
// console.log('Caught observable exception and returning it');
// return Rx.Observable.return(e);
});

//subscribe to observable to kick it off
source.subscribe(function(i){
console.log(i)
});

//shows we got to the end of the program. We never get here unless we catch the observable exception
console.log('last statement running');

Outputs:

"running promise"
"about to throw exception in promise"
"NOTE: promise swallows exception and continues"
"running observable"
"about to throw exception in observable"
X "Uncaught Error Observable (line 34)"

Removing the comments from the following lines:

1
2
3
// }).catch(function(e){
// console.log('Caught observable exception and returning it');
// return Rx.Observable.return(e);

Outputs:

"running promise"
"about to throw exception in promise"
"NOTE: promise swallows exception and continues"
"running observable"
"about to throw exception in observable"
"Caught observable exception and returning it"
"Error Observable"
"last statement running"

I don't have a Pro account, but you can play with the JS Bin version.

Babel transpile ignoring native Javascript

I was thinking today that we want Babel to ignore transpiling native JavaScript available in Node.js.

You could whitelist or blacklist what you want Babel to transpile and a few people list options in the comments here.

Babel 6 now does nothing by default, but there doesn't seem to be any Node.js version specific presets mentioned on the Babel page.

Finding out which options you need for your version of Node.js might be a bit tricky.

The famous Kangax page for ES6 (yes, I prefer that name rather than ES2015 too) is a good source and shows some different Chrome and Node.js versions.

This link on the Node.js site shows what features are available in Node.js, but I am not sure how up to date it is kept.

It notes you can find in progress V8 options with:

 node --v8-options | grep "in progress"

and the V8 version used by your Node.js with:

 node -p process.versions.v8

Are Google Dropping the Ball with Android

I've been using Android phones for a while now. Lately however, it has been a pot of boil and trouble. Lollipop issues, Kit Kat issues, Hangouts and Chrome issues spring to mind. It's time to try something else as outlined below.

Nexus 4 Problems

I have a Nexus 4 which was running great on Kit Kat. I made a fairly early move to Lollipop and was hit by early mover issues like many others. Okay, this is somewhat expected with a new release.

As updates came for Lollipop, issues came and went. Sometimes it was even worse than before, with my phone randomly turning off etc.

Now that the Nexus 4 has been dropped off the Marshmallow update list, I am at the end of the road for Google updates. Problem is, my phone still randomly switches off during media playback, like video calls.

Hangouts seems to perform really poorly lately and is unusable when talking to someone with poor internet. The Line app handles this a lot better.

Hangouts also seems to have some issues on my desktop computers as well. Windows going missing, login issues. Sometimes it just needs killing and restarting.

Chrome browser on Android has also been having issues getting stuck in the search area and not wanting to do anything. This only seems to be solved by closing Chrome from the task manager.

I've talked to other people and they have seen similar issues with Chrome and Hangouts. A few also seem to be annoyed with their Android devices.

Motorola XT905

I also had an older device that is still in use, but was recently offered an update to Kit Kat. Not learning my lesson from Lollipop updates, I actually installed Kit Kat. Turns out I should have investigated more. Plenty of people seem to have the same issue of Wifi range halving, which means it is unusable in half of the house.

The Answer?

Well, I bought a MacBook, but I am not quite ready to saddle up for the iOS ride.

Microsoft Windows change their phone OS every 5 minutes. The last few people I knew with a Nokia Windows phone both ended up with bricks.

So I have installed CyanogenMod 12.1 on the Nexus 4. Good thing I am a developer and already had the necessary Android dev tools installed. After a couple of issues with the instructions I eventually got there.

Initially I downloaded the Cyanogen Recovery image that was associated with the CyanogenMod Build I downloaded. This didn't match the instructions I was using and seems less featured than the Team Win Recovery software I later installed.

CyanogenMod installation instructions for Nexus 4

Another issue I faced was the "stock" version of Open GApps was apparently too big to install. I used the "nano" version, which is probably nicer anyway as I can install what I need.

Too early to tell yet if the issue is solved, but we shall how it goes after some testing.

Update

Seems like a no go so far. One crash already. Maybe I will need need to try Kit Kat (CyanogenMod 11)!

Moving to a MacBook from Windows

Yes, MacBook to PC, or OS X to Windows makes more sense, but whatever you want to call it, I finally caved in and bought a MacBook (well a few weeks ago now).

Why?

Well every other developers seems to have one in all the videos I watch, so I decided I better have one too... just kidding. Well, kidding about the reason, but seriously, it is a sea of MacBooks in most online videos I watch.

I still have my older Windows notebook and I am going to try take both with me next time I travel. I still like Windows and there are some programs I still prefer that are only available on Windows.

The main reason that made me look was that you have pretty much have to have a MacBook if you want to make anything for OS X or iOS. I may go down that path, hence the MacBook.

I am also doing some Node.js development and whilst I have got along so far with Windows, it still feels like a second class citizen. Most people seem to develop for Node on a MacBook.

I'm also pretty keen to get a decent terminal. Babun and ConEmu made life a bit more bearable, but a Unix based system will be nice again.

Why Now?

I have been hanging out for an Intel Skylake processor for a while, but I'm currently in Australia and the price was recently increased here due to the poor Australian dollar. I managed to get a MacBook Pro 13 Retina on sale with the discount applied to the old lower price. I can also claim tax back when I fly out soon.

I'm also thinking they will do a major chassis update to the new Skylake MacBook, so it is a bit of a bummer. Anyway, I will have to wait and see if I made the correct decision or not. I figured I can always sell it and upgrade as MacBooks seem to hold their value very well. At least I managed to get a Broadwell CPU after all the waiting.

It may turn out better if they move everything to the new MacBook 12 inch keyboard, as that felt horrible, haha. Not that I thought I would like this keyboard, but more on that later.

How's it Going?

Well I have some more articles planned for that, so I'll update those soon.

I've never really liked Macs when I have used them before, so it was going to be interesting. I have been trying to keep an open mind and so far it is turning out better than I thought.

Install fails because module 'is-property' isn't installed

I was having some weird compile errors while trying to use node.js or io.js.

"Install fails because module 'is-property' isn't installed" was another one of them.

This git issue reports there are some bugs in the Windows version of io.js to do with paths of more than 259 characters.

After upgrading to io.js 2.3.1 I seemed to get around at least this issue.

Writing node.js on Windows so far feels like a bit of a battle!