Olivier Lalonde's blog

Hey. I'm a friendly hacker, HN addict and startup guy. I tweet as @o_lalonde.

Introducing Boolasync - a Library for Async Boolean Logic

Who would have thoughts things would have gone that far? Yes, I have created a Javascript library for handling boolean logic that involves asynchronous callbacks.

Let’s say you have a web app that has an authorization layer like so:

1
2
3
if (is_user() && (is_admin() || is_super_admin()) {
  console.log('Authorize!');
}

Note: this is a fictional example for demonstration purposes.

However, here is the catch: your functions are asynchronous which means that they take a callback argument which in turns takes an error and result argument. function callback(err, res) {}

How do you rewrite the above code elegantly?

You could use the nice async library.

1
2
3
4
5
6
7
8
9
async.parallel([
  is_user,
  is_admin,
  is_super_admin
], function (err, results) {
  if (results[0] && (results[1] || results[2])) {
    console.log('Authorize!');
  }
});

There are two problems however:

  1. The code is not very expressive.

  2. We have to wait for all functions to finish.

    In the example above, if is_user returns false, we would already know that the user is not authorized. false && ... is always false no matter what the ... represents. In computer science, this is called lazy evaluation.

Here is how you would rewrite the above with boolasync:

1
2
3
4
5
is_user.and(is_admin.or(is_super_admin)).eval(function (err, authorized) {
  if (authorized) {
    console.log('Authorize!');
  }
});

Notice how terse and expressive the code is compared to the async example. In bonus, boolasync won’t wait for an async call to terminate if it already knows the result of an expression.

For more documentation and examples, visit the Github page: https://github.com/olalonde/boolasync

Cheers!

Executing Multiple Shell Commands Cleanly in Node.js With Async

1
2
3
4
5
6
7
async.parallel([
  async.apply(exec, 'git rev-parse HEAD'),
  async.apply(exec, 'git symbolic-ref --short HEAD')
],
function (err, results) {
  console.log(results);
});

First, the async.parallel call executes all functions in the array concurrently. If you need the commands to be executed in order, use async.series instead. async.apply returns the function passed as a first argument with values already applied to its arguments and sets the async.parallel callback for us. Finally, the last functions receives the results in order when all functions have finished executing. It preserves the order of results as you would expect them.

For more info:

https://github.com/caolan/async

My Biggest Vim Productivity Boost

This week I added the following snippet to my .vimrc (.vimrc.after if you are using Janus):

1
2
3
4
map <C-J> :bnext<CR>
map <C-K> :bprev<CR>
map <C-L> :tabn<CR>
map <C-H> :tabp<CR>

It maps CTRL-j and CTRL-k to next and previous buffer and CTRL-l and CTRL-h to next and previous tabs.

It is by far the biggest productivity boost I have gotten out of my .vimrc file.

Buffer and tab switching has never been that fast and easy.

Macbook tip: remap your CAPS LOCK key to CTRL.

Connectr: Programmatically Manipulating the Connect Stack

Connectr is a Node.js module I wrote that aims to solve the following problem: how to manipulate the Connect stack after it has been created.

This is a problem I faced while writing a REST framework on top of Express.js. The framework initialized the middleware stack but there was no easy way to expose the stack to end users of the framework so they could add their own middlewares at arbitrary positions on the stack.

Install

npm install connectr

Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var connectr = require('connectr')(app);

// Add labeled middleware
connectr.use(middleware).as(label);

// Insert before middleware
connectr.before(label).use(middleware).as(label);

// Insert after middleware
connectr.after(label).use(middleware);

// Remove middleware
connectr.remove(label);

// the .as, .before and .after calls are optional

Simple Example

1
2
3
4
5
6
7
8
9
10
11
12
var connect = require('connect'),
var app = connect();
var connectr = require('connectr')(app);

connectr.use(connect.cookieParser).as('cookieParser');

/* ... */

connectr.before('cookieParser').use(function (req, res, next) {
  console.log('Before cookie parser...');
  next();
}).as('log before cookie parser');

I am hoping the methods that Connectr provide can eventually be supported natively by Connect but until then, Connectr does the job.

If you use Connectr, please star the project on Github to show your support.

Happy coding!

Pagination With Handlebars

Pagination can be quite tricky with Handlebars since Handlebars does not have any built in way to do for/while loops. One solution mix some presentation code within your logic layer and passing an array containing all your pages in an array.

For example:

1
2
3
4
5
6
7
8
9
10
{
  pagination: [
    { previous: disabled },
    { page: 1, active: true },
    { page: 2 },
    { page: 3 },
    { page: 4 },
    { page: 5 }
  ]
}

This solution has several drawbacks: mixing of logic/view code, code duplication, difficult to reuse, etc.

The other, cleaner solution, is to write a Handlebars helper, which I have already done so you don’t have to!

screenshot

The helper is available for download or forking on Github:

https://github.com/olalonde/handlebars-paginate

or through NPM:

1
npm install handlebars-paginate

To use it, all you have to do is register it as an helper:

1
Handlebars.registerHelper('paginate', require('handlebars-paginate'));

And all you need to pass to your template is an object containing a page parameter which is the number of the current page and a pageCount parameter which is the total number of pages.

For example:

1
2
3
4
5
6
{
  pagination: {
    page: 3,
    pageCount: 10
  }
}

Handlebars-paginate let’s you define three types of blocks in your template:

middle:

This will iterate over all the possible pages. An optional limit parameter is available if you’d like to limit how many page links to display. limit=7 will only display 3 links to the left of the active page and 3 pages to its right.

For example:

1
2
3
{{#paginate pagination type="middle" limit="7"}}
  <li {{#if active}}class="active"{{/if}}><a href="?p={{n}}">{{n}}</a></li>
{{/paginate}}

previous and next:

Finally, previous and next are used to define how you want to display the “previous” and “next” buttons.

For example:

1
2
3
{{#paginate pagination type="previous"}}
  <li {{#if disabled}}class="disabled"{{/if}}><a href="?p={{n}}" >Prev</a></li>
{{/paginate}}
1
2
3
{{#paginate pagination type="next"}}
  <li {{#if disabled}}class="disabled"{{/if}}><a href="?p={{n}}">Next</a></li>
{{/paginate}}

Enjoy and feel free to fork or report issues!

How to Follow HTTP Redirects in Node.js

One of the biggest annoyance with Node.js’ native HTTP and HTTPS clients is that there is no way to automatically follow HTTP redirects. Let’s say you want to fetch the content of a page that has moved (301 redirect), you will have to write a lot of boilerplate code to handle the redirect(s) by yourself.

Since following redirects is fairly common, I decided to write a a drop-in replacement for the native HTTP and HTTPS module that would handle redirection seamlessly.

This module has exactly the same interface has the native HTTP and HTTPS module but it will handle redirects automatically. In other words, if you want to automatically start following redirects, all you have to do is replace

1
var http = require('http');

by

1
var http = require('follow-redirects').http

Before that, you will of course need to install the module through NPM:

1
npm install follow-redirects

Here are some usage examples:

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
29
30
31
var http = require('follow-redirects').http;
var https = require('follow-redirects').https;

/* 
 * http and https are just like Node.js' http and https modules except 
 * that they follow redirects seamlessly. 
 */

http.get('http://bit.ly/900913', function (res) {
  res.on('data', function (chunk) {
    console.log(chunk);
  });
}).on('error', function (err) {
  console.error(err);
});

/*
 * You can optionnally pass the maxRedirect option which defaults to 5
 */

https.request({
  host: 'bitly.com',
  path: '/UHfDGO',
  maxRedirects: 3
}, function (res) {
  res.on('data', function (chunk) {
    console.log(chunk);
  });
}).on('error', function (err) {
  console.error(err);
});

More info is available at the Github repository: https://github.com/olalonde/follow-redirects/

Tips and Tricks When Learning a New Technology

In this post, I’ll share some tricks I use before diving into a new technology. Technology could mean anything from programming language to an operating system (note that some steps are specifically for programming languages/frameworks).

For the sake of demonstration, I’ll pretend that I want to learn the Haskell programming language.

Wikipedia

wikipedia logo

Get a high level perspective of the technology by reading its Wikipedia page.

http://en.wikipedia.org/wiki/Haskell_(programming_language))

Hacker News

Hacker news search screenshot

Get hands on feedback from people who have previous or current experience with the technology through comments. Find interesting articles about the technology (by popularity or date) through stories.

Stories: http://www.hnsearch.com/search#request/submissions&q=haskell&sortby=points+desc&start=0

Comments: http://www.hnsearch.com/search#request/comments&q=haskell&sortby=points+desc&start=0

StackOverflow / StackExchange

stackoverflow logo

Find out the highest voted questions relating to the technology. It is very likely that you’ll have those questions as well when learning the technology so why not find out the answers right now. There will also usually be a question about the best resources to learn from. This can be a good starting point for your own learning process.

http://stackoverflow.com/search?tab=votes&q=title%3ahaskell

http://stackoverflow.com/questions/tagged/haskell?sort=votes&pagesize=15

GitHub

github logo

Find out the most popular open source projects that relate to the technology. This is especially helpful when you start a project with this new technology and aren’t sure which are the latest and greatest libraries to use. It’s also a good idea to study the codebase of open source projects to get familiar with common idioms and coding styles.

https://github.com/search?langOverride=&language=Haskell&q=language%3Ahaskell&repo=&start_value=1&type=Repositories

IRC

irc screenshot

Find out if the technology has an IRC channel. You can usually find that out by simply connecting to Freenode and joining #technology-name or Googling irc technology-name.

https://www.google.com/?q=haskell%20irc

Conclusion

Don’t forget many people have gone through what you are about to go through. Don’t repeat the same mistakes they did and leverage every piece of information you can from them!

I’d love to hear more tips and tricks in the comments below.

Using the Debugger Statement With Node-inspector

The first thing client-side Javascript developers miss when starting out with Node.js is the ability to debug their code through a GUI debugger as they are acustomed to when developing for the browser.

Fortunately, it wasn’t long before the Node.js community came up with GUI debuggers and as of today, the most widespread one is node-inspector.

In this post, I won’t go into the details of using node-inspector but I will instead introduce a neat feature that many Node.js developers aren’t aware of or don’t know how to use.

This feature is called the debugger statement. If you have ever caught yourself firing up node-inspector and browsing through the huge file pane on the left in order to find a file and insert a breakpoint, then this post should save you a lot of trouble in the future.

Here’s what the ECMA-262 specification has to say about the debugger statement:

Syntax

DebuggerStatement :

debugger ;

Evaluating the DebuggerStatement production may allow an implementation to cause a breakpoint when run under a debugger. If a debugger is not present or active this statement has no observable effect.

In other words, you can insert breakpoints directly in your code using debugger;, fire up your app in debug mode, open your debugging client and the breakpoint will be set. Don’t forget to remove debugger; from your code once you are done debugging!

Here’s a quick demonstration.

  1. Insert debugger; statement in your code

    screen shot

  2. Fire up node-inspector

    bash node-inspector;

  3. Launch your app in debugging mode (don’t forget to use the --debug-brk flag if your debugger statement is “early” in your code)

    bash node --debug server.js

  4. Open the debugging client

    screenshot

No more hunting for files!

Don’t Run Node.js as Root!

The root user on Linux and Unix operating systems is a special user that has absolutely total power over a machine. It is therefore very important to use the root account only when absolutely necessary and preferrably through the use of a program such as sudo. From Wikipedia:

In operating systems which have the concept of a superuser, it is generally recommended that most application work be done using an ordinary account which does not have the ability to make system-wide changes.

Indeed, if you are running your server as root and it gets hacked through a vulnerability in your code, the attacker will have total control over your machine. This means the attacker could potentially wipe out your whole disk or worse. On the other hand, if your server runs with the permissions of a regular user, the attacker will be limited by those permissions.

The problem most Node.js developers will face is that in order to open ports below 1024 (i.e. port 80), one has to possess superuser permissions. There are a few solutions around that problem, one being the use of iptables to redirect port 80 to a higher port such as port 3000 and another one being the use of a proxy such as nginx that will redirect requests to your server. However, today I will focus on a solution that can be done entirely within your code.

We still start our server with root permissions using sudo but once we have opened our port(s), we will revert back our server’s permission to that of a regular user using a special trick. That trick is to read the SUDO_UID environment variable which sudo passes to any process it launches and using Node’s global process.setuid() function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var http = require('http');

var app = function(req, res) {};

http.createServer(app)
  .listen(80, function(err) {
    if (err) return cb(err);

    // Find out which user used sudo through the environment variable
    var uid = parseInt(process.env.SUDO_UID);
    // Set our server's uid to that user
    if (uid) process.setuid(uid);
    console.log('Server\'s UID is now ' + process.getuid());
  });

No excuses for running your server as root anymore!

A Better Require() for Node.js

UPDATE: better-require now supports json, yaml, csv, xml, ini as well as coffeescript, clojurescript, typescript, dart and six.

While reading the Node.js API documentation today, I stumbled upon an interesting feature. This feature let’s you add handlers for arbitrary file extensions that require() will call when requiring a file of that extension. Internally, it looks for the extension in require.extensions and if the extension is found, the handler is called instead of the default require routine.

I thought that was pretty cool so I couldn’t resist the urge of wrapping a bunch of file parsers into a standalone NPM module that would make it easy to support for multiple file formats through require().

This gave birth to better-require.

npm install better-require

If allows developers to seamlessly require json, yaml, csv, xml and ini files without having to deal with require.extensions or finding the appropriate parsing libraries. It is also easily extensible so feel free to fork and add additional file formats!

Here’s a usage example:

1
2
3
4
5
6
7
8
9
10
11
require('better-require')('json yaml xml');

// we can now require .xml, .yaml and .xml files!

var yaml = require('./config.yaml')
  , json = require('./config.json')
  , xml = require('./config.xml');

console.log(yaml);
console.log(json);
console.log(xml);

Enjoy!