From Flux to Redux: Async Actions the easy way

The Flux architecture is based on some great ideas (check out our visual cheatsheet if you want to know more), but we found a big flaw when implementing it through Facebook’s own Dispatcher implementation. This brought us to Redux, a flux-inspired library that received high praise from the Flux creator herself.

Redux is very young and really tiny at 2kB, but already incredibly stable and feature rich. It is also a very non-opinionated library, and the just completed (almost) docs are very keen to point out how you can do things in many different ways. This is great if you already have your strong preferences, but doesn’t help the newcomer.

One thing some of us found particularly hard to digest was the documentation for Async Actions, so I wrote a simplified version to use with my team. You can find it below; it is based on the Todo List example in the “Basics” section of the docs: if you didn’t read that already, you should do it now.

Async Actions the easy way

As opposed to Flux, In Redux action creators must be pure functions with no side effects. This means that they can’t directly execute any async code, as the Flux architecture instead suggests, because async code has side effects by definition.

Fortunately, Redux comes with a powerful middleware system, and one specific middleware library, redux-thunk, that allows us to integrate async calls into our action creators in a clean and easy way.

First of all, we need to integrate the redux-thunk middleware into our store. We can do this in the Todo List example by changing a few lines inside index.js; from this:

import React from 'react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import App from './containers/App';
import todoApp from './reducers';

let store = createStore(todoApp);

To this:

import React from 'react';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import App from './containers/App';
import todoApp from './reducers';

let store =  applyMiddleware(thunk)(createStore)(todoApp);

Before this change, store.dispatch could only accept simple Action objects. With redux-thunk, dispatch can also accept a thunk function.

  • If dispatch receives an Action object, redux-thunk will do nothing, and the reducers will get called with the action as usual, and change the state synchronously.
  • If instead dispatch receives a thunk function, redux-thunk will execute it. It will be the thunk function’s responsibility to actually dispatch an action object. More importantly, the thunk function doesn’t need to be pure, so it can contain async calls, and can dispatch some (synchronous) action only after the async call has finished, also using the data received from the call. Let’s see this with a simple example for the Todo app.

In a real app, we’ll want to keep our Todo list synchronized with our server. For now we’ll only focus on the addTodo action creator; the one from the Basics section will only update the state in the client. Instead, we want it to:

  • Optimistically update the local state and UI
  • Send the data to the server, so it can update the DB
  • Manage the server response

To achieve this, we still need our “optimistic” addTodo action creator, but we also need an async thunk action creator to handle the whole async process. To keep the changes to the code at a minimum, we’ll rename the optimistic action creator, but not the action type that is sent to the reducers (and used in the switch statement to act). This code goes into actions.js:

// renamed optimistic action creator - this won't be called directly 
// by the React components anymore, but from our async thunk function
export function addTodoOptimistic(text) {
  return { type: ADD_TODO, text };

// the async action creator uses the name of the old action creator, so 
// it will get called by the existing code when a new todo item should 
//  be added
export function addTodo(text) {
  // we return a thunk function, not an action object!
  // the thunk function needs to dispatch some actions to change 
  // the Store status, so it receives the "dispatch" function as its
  // >first parameter

  return function(dispatch) {
    // here starts the code that actually gets executed when the 
    //  addTodo action creator is dispatched

    // first of all, let's do the optimistic UI update - we need to 
    // dispatch the old synchronous action object, using the renamed 
    // action creator

    // now that the Store has been notified of the new todo item, we 
    // should also notify our server - we'll use here ES6 fetch 
    // function to post the data
    fetch('/add_todo', {
      method: 'post',
      body: JSON.stringify({
    }).then(response => {
      // you should probably get a real id for your new todo item here, 
      // and update your store, but we'll leave that to you
    }).catch(err => {
    // Error: handle it the way you like, undoing the optimistic update,
    //  showing a "out of sync" message, etc.
  // what you return here gets returned by the dispatch function that 
  // used this action creator
  return null; 

The above code and its comments show how you can do async calls, mixing them with optimistic updates, while still using the usual syntax: dispatch(actionCreator(...)). The action creator itself is still a pure function, but the thunk function it returns doesn’t need to be, and it can do our async calls for us. If needed, the thunk can also access the current store state, as it receives getState as its second argument: return function(dispatch, getState) { ...

That’s all! If you want to learn more about Redux, you can find the full docs here:

Flux Architecture Visual Cheatsheet

At we recently started experimenting with the React library, and, right from the start, I really liked what I saw.

After that, I also went to study the Flux architecture, and, honestly, I found the official overview and tutorials rather confusing.

After studying those better, and after some more reading around, I think I understood where the confusion came from. Flux is itself – just like the whole Javascript ecosystem – in a period of very intense flux, and the docs aren’t really keeping up with that.

I realized that the Todo List tutorial – the first one you’re supposed to learn from, as I dutifully did – illustrates an older version of Flux, and isn’t even up to date to the recent changes to the Todo List example code on github. I’m pretty sure the Facebook team will fix this soon, but for now this really doesn’t help.

Anyway, in the end, I understood that Flux is much simpler than many wordy explanations make it look. To spare my team my initial pains in getting it, I created a diagram – a visual cheatsheet – to better illustrate how it works, based on the latest code examples by Facebook. The team found it useful, so I decided to give back to the community and publish it here.


It’s meant to be a companion to the official docs and tutorials, not a complete explanation. But most of the core concepts are there. The code snippets are from the Chat example app.


EDIT: some people are having problems with the link or want to download a simple image. This will be uglier when zoomed and without links, but here you go with a simple PNG export: Flux Architecture Visual Cheatsheet (png)

UPDATE: after trying to use Flux with Facebook’s own Dispatch library, we decided to instead use Redux. You can read some background in my new post about Redux Async actions the easy way.

Redis: Migrate Keys From One Instance To Another Based On Pattern Matching [node.js script]

If you work with Redis and a fairly big dataset it’s pretty likely that, at some point, you’re going to fill up all your RAM. This already happened to me more than once with; the easy fix, if the growth is slow enough, is to just add more memory.

Simpsons_Duff_Lite_DryWhen that doesn’t work anymore, the next move – while waiting for Redis cluster – is quite likely going to be using some manual sharding technique. When you do, you’ll probably going to need to split your dataset among more instances.

This is exactly what just happened to me, and I didn’t find any ready recipe or solution to easily split my rather large dataset. So I ended up creating a small node.js script which doesn’t use too much memory and that you can find here:


Facebook Hashtags: When Monetization Clashes With Branding

Considering that my startup CyBranding owns a thriving website named and sells a product called Hashtag Intelligence, you could easily see why hashtags (probably) coming to Facebook is very good news for me. But, as a person very interested in branding, I can’t help questioning this move from the Facebook brand point of view.

For its users, Facebook’s core expectation can be described as “easily sharing with friends and family through the Internet”. It is a very compelling expectation, Facebook owns it in the mind of billions of people, and thus their website has become the most engaging in the World as all the stats about time spent online tell us.

Facebook’s problem is that its core expectation isn’t as easy to monetize with advertising as, for example, Google’s “quickly finding what I need on the Internet”. Or even Twitter’s “publicly sharing on the Internet”, which is much less compelling than Facebook’s to most people, but which has that “publicly” attribute that makes it much more compatible with infotainment and advertising.

Facebook already took many steps towards making itself a better platform for the public sharing and consuming of content – think pages, “follow”, privacy changes, etc. – so adding hashtags, that were integral to Twitter’s success in that space, would only be a logical move in that same direction. The big risk for Facebook here is that this move could actually work – and, if it will work, it will also significantly dilute Facebook’s brand expectation of “sharing with friends”.

Why is that a big risk? Because public and personal don’t mix well; by diluting its core expectation, Facebook would leave the door open to some competitor completely focused on “personal”. This move could very well bring a short and medium-term benefit to Facebook’s bottom line and market capitalization, but, by putting in jeopardy its nearly complete domination of its current, incredibly compelling focus on “friends and family”, it could also sow the seed of its own undoing.

The good news? After all, if the history of branding has something to teach us, Facebook is most likely not going to “become the Internet”, closing us all inside a walled garden. In the world of brands, you just can’t be everything to everybody.

[UPDATE] I just read an article on Time about the “tragic beauty of google“, where the author says that he likes Facebook more because it feels more “warm, personal”. Will it still feel that way if the move toward more public conversations will work?

A Little Cross-Platform Productivity Boost

Sometime it is difficult to concentrate on the task at hand – especially if you are almost always at work, with a day job and a startup on the side. At those times, I find it particularly difficult to resist the temptation to compulsively wander to some interesting websites, like Hacker News or some other online news source.

I already had a little Windows software installed to block a list of distracting websites for a given time when I need it, but I often code on Linux and that program doesn’t work there. That’s how I came across Concentrate for Chrome, a Chrome extension that does that same thing – but works equally well on Windows and Chrome.

If you’re like me, and sometimes being a news-aholic interferes with your being a workaholic, this extension is highly recommended!

Are “Shameless Plugs” Worth It? Some data

I recently published two posts that reached the home page of Hacker News: The first one was the announcement of my ABalytics library for client-side A/B testing; the second one was about a new version Hacker News: Mark All Read, a Chrome extension I wrote to save time on HN.

Both posts are about little projects that I originally built for my own use, and then polished, published and open sourced to give back to the community… and to get some publicity; specifically, with these two posts, I wanted to promote this new blog and the fact that I’m now open for consulting as a way to finance my startup project(s). With the post about ABalytics I didn’t include any direct reference to those other news: I just relied on the curiosity of visitors, and the prominent “Consulting” and “Portfolio” links in the blog menu.

These were the results:

In short, only 0.3% of visitors went on to read about me, and 0.16% read my “Consulting” page.

On the contrary, I ended the post about HNMarkAllRead with a “Shameless Plug” section, detailing the fact that I’m open for consulting projects. This is what happened:

This time, 3% of those who read the post also read my Consulting page – which was directly linked in the post – and 0.4% went on to read the About page. That’s a tenfold increase in clickthrough rate; something that could be expected, considering how much more prominent the link was, but it’s good to have some solid data about it.

And what about the downsides?

That’s very difficult to determine, at least with just two data points. I didn’t have any bad reactions or comments, but there was one possibly alarming sign. The ABalytics post had many less uniques, because it was picked up in the HN home page an hour later than it was posted to HN, and so it never went near the top of the page, but it generated many more social media shares than the other post: 171 (between Twitter, G+, LinkedIn and FB) to 73; that’s a 3.8% vs 0.6% “social media conversion rate” in favor of the post without the plug.

How much was this very big difference in social media reactions a consequence of me being shameless at the end of the post? With just these two data points, it would be impossible to tell – the posts are about very different things. But back in May I published the first announcement of Hacker News: Mark All Read, and – even if I later moved the post from another blog to this one – I was able to recover at least the Twitter shares data for an apple to apple comparison.

That first announcement generated 39 tweets, out of 8,986 uniques: 0,42%. Considering just the Twitter reactions to the latest post – the one with the plug – the rate is 0,49%. No noticeable change caused by my being shameless.

So, the bottom lines is: If what you want is to get your portfolio in front of your blog readers, closing your posts with a shameless plug looks definitely worth it (at least according to this very little sample). After all, the readers are getting your content for free, it’s only fair that they cut you some slack :)

Save Even More Time On Hacker News

Some months ago I published a Chrome extension I had developed for myself to save time on HN; it allowed you to “mark as read” the news items that you already read or scanned.

The Chrome store tells me that 770 users are using it weekly, so I decided to take the time to update it with some more features that I’ve been experimenting with lately and found very useful.

Mark comments as read

The new feature I found most useful is the ability to also mark comments as read.

Using the orange button, you can mark all comments in the page as read. If you do so, those comments will appear with a slightly darker background, so when you reload the page you can easily spot the new ones – I found this a real time saver!

If you want to find the new comments even faster, you can check the “Hide read comments” option. This mode can be a little confusing, as you lose the context for the comment, but sometimes I found it useful anyway.

Follow comments for a news item

Sometimes, even if you already read an item and its comments, you want to follow the discussion as it develops, or be notified if a discussion starts at all. Instead of just leaving the comments page open, you can now tick the “Follow comments” checkbox (see picture above); when you do so, the news item will be shown in the home page even if it was marked as read and you are hiding read items.

Most importantly, if there are new comments since you marked all comments as read for that item, that will be shown with a green text in the home page. This can also be a good time saver – if you resist the urge to follow too many discussions, at least.

Collapse comment threads

This is a pretty obvious feature, but it helped me save time when, for example, the first comment for an item is something contentious that generated a long thread I’m not interested in. Just click the little “-” symbol to the left of the root of the thread, and the thread will collapse.

You can also collapse all thread with the “‐‐” to the left of the “Follow comments” checkbox. “+” and “++”, of course, will respectively expand one thread and all threads.

Show parent comment

I left the fanciest feature last; I don’t use it very often, but when I do I find it incredibly useful.

I like threaded comments, but sometimes you just get lost in them: You read a long sub-thread, then you find a comment answering something, but you can’t understand what it’s answering to. How can you find that out? Enters “show parent”.

With this feature, when a comment is part of a thread, but not the first answer to its parent, a “show parent” link appears. You can hover your mouse pointer on that link, and the mysterious parent is shown right above it. I really like this solution because it is non-intrusive and (in my opinion) solves a real pain of threaded comments. The only serious limitation I see is that it wouldn’t work well on touch screens, but if somebody wants to adopt it for that use case, it could become a touch-to-toggle.

Wow! How much do I need to pay for all this?

Nothing! You can get the extension for free from the Chrome store.

Other browsers? It’s open source

I packaged this as a Chrome extension because it’s just too convenient. If you want to use it on some other browsers, though, you’re free to get the source code on github and adapt it any way you want. Happy hacking!

Shameless plug

Did you like this project? Do you need somebody to help you develop your web app or idea? I just started to be open for consulting projects. If you need an expert at translating ideas into software solutions, from requirements analysis to full stack development, check out what I could do for you here.

ABalytics.js: Client-side A/B Testing With Google Analytics

I recently wanted to conduct a little bit of A/B testing on a project of mine, so I went exploring – yet again – the free options.

There are lots of very good server-side solutions, but what I wanted was one that I didn’t need to configure on the server, and that could be integrated into Google Analytics, where I already track my websites performances. I found on the web some how-tos about the use of GA custom variables for A/B testing, but no ready-made libraries to do so.

So I created my own javascript library; it is so simple that I decided to implement it without any external dependencies, so that if in the future I want to use it without jQuery (which I usually use) I’ll be able to do so. And it is so simple that it was easy to give a minimum polishing and make it ready to publish, to give it back to the community.

These are the main features:

  • Easy to set up
    • You just list the possible variants, the randomization is handled automatically
    • You just mark the html elements you want to test on with a class, the substitution is automatic
    • No need to set anything up server side, all the results are stored on Google Analytics
  • Consistent user experience: The selected variant is stored in a cookie, so the user will see the same one when coming back
  • No external dependencies: Pure javascript, you just need to include GA
  • Flexible: You can conduct multiple, independent experiments at the same time. Each experiment will use a custom variable slot

I’m releasing the library with an MIT license, and you can find it – with basic instructions on how to use it – on Github. Enjoy!

A new home for my technical, startup-related, and personal posts

A little more than one year ago I started a blog about my then-latest website, Soon after launching it, I started publishing more and more posts that weren’t directly related to that website, but more about technical and startup-related subjects in general.

That arrangement didn’t feel the best to me, so I decided to split that blog in two, moving all not-hashtagify related posts to a new personal blog, the one you’re reading now. That’s why you might find here some posts that you already read elsewhere: This one is the first post I published directly on, and all older ones come from

So, if you get that weird deja-vu sensation while reading some older post here, don’t worry: It’s perfectly normal to feel that way while you’re caught right in the middle of a reconfiguration of the Matrix!