NodeJS: Generator Based Workflow

This post assumes you already know about Promises, Generators and aims at focusing more on the co library and the generator based workflow it supports. If you are not very familiar with Promises or Generators, I would recommend you study them first.

Promises are nice

Promises can save us from the callback hell and allow us to write easy to understand codes. May be something like this:

Here we have a promisedOne function that returns a Promise. The promise is resolved after 3 seconds and the value is set to 1. For keeping it simple, we used setTimeout. We can imagine other use cases like network operations where promises can be handy instead of callbacks.

Generator Based Workflow

With the new ES2015 generators and a nice generator based workflow library like co ( , we can do better. Something like this:

What’s happening here? The co function takes a generator function and executes it. Whenever the generator function yields something, co checks if the object is one of the yieldables that it supports. In our case, it’s a Promise which is supported. So co takes the yielded promise, processes it and returns the results back into the generator. So we can grab the value from the yield expression. If the promise is rejected or any error occurs, it’s thrown back to the generator function as well. So we could catch the error.

co returns a Promise. So if the generator function returns any values for us, we can retrieve those using the promise APIs.

So basically, we yield from the yieldables, catch any errors and return the values. We don’t have to worry about how the generator is working behind the scene.

The co library also has an useful function – co.wrap. This function takes a generator function but instead of executing it directly, it returns a general function which returns a promise.

This can often come handy when we want to use co with other libraries/frameworks which don’t support generator based workflow. For example, here’s a Gist that demonstrates how to use generators with the HapiJS web framework – The route handlers are written using generator function and then adapted using co.wrap for Hapi.

Deploying a NodeJS 5 app with nginx on Ubuntu

In this blog post, we would follow the steps to deploy a NodeJS app using the latest version of Node with nginx on Ubuntu.

Installing Node.js 5

The official repository on Ubuntu doesn’t ship the latest version of NodeJS yet. So we will use a third party source to install it from:

Using PM2

I love PM2 for keeping my node apps alive. If you didn’t know, PM2 is an awesome tool that launches Node processes and monitors them. If it crashes, it can restart them. PM2 is very easy to setup and use. It’s also quite feature packed.

We would setup PM2, launch our app with it and then generate a launch script so PM2 itself is started on system reboot.

Nginx Configuration

Now that the app is running, it’s time to setup nginx as our reverse proxy. Here’s the default configurations I use:

Live Debugging Webhooks with Ngrok

ngrok is an awesome service – it creates secure tunnels to localhost. With ngrok, you get a url like which is actually tunnel to a port to your local machine. So any request you make to that url is served by the app that you run on that port.

I know there are many cool services to debug webhooks like Requestbin – but the main benefit of ngrok is the app keeps running on your app, serving live traffic. So you can debug it in real time.

In this blog post, we would use a Node.js server with ngrok to serve Mandrill webhook requests.

Installing ngrok

Downloading and installing ngrok is pretty easy as you can find here — However, if you’re on OS X and use Homebrew, you can install it with just one command:

Creating a Node.js App

Here’s a sample Node app that listens on port 3000 and parses the mandrill payload using body-parser package.

Tunneling Traffic

Once we have the app running on port 3K, we can ask ngrok to create a tunnel for us. For this we just need to pass the port number to the ngrok command:

We would get an url soon afterwards. We can use this url to POST requests. In our case, go to your Mandrill account and create a webhook. Mandrill will send events to this url and it will be served by your app, running locally on your machine. You can make changes to the codes and restart anytime.

Awesome, no?

Using ES7 async/await today with Babel

Let’s take a code snippet that contains the demonstration of async/await — – our objective is to transpile this piece of code to ES5 (current day Javascript) so we can run it with today’s version of NodeJS.

You will notice a command on top of the snippet which no longer works because Babel JS has changed. I am going to describe how we can do it with the latest version of babel as of this writing (6.1.4 (babel-core 6.1.4)).

Install Babel and Plugins

The new Babel depends on individual plugins to transform and parse codes. To transform async functions, we shall use the transform-regenerator plugin. We also need to add the syntax plugin to recognize the async/await syntax. Otherwise Babel won’t recognize those. Apart from that, we also install the ES2015 preset which includes a sane set of plugins for transforming ES6 to ES5. We will keep those so we can use other ES6 goodies.

First we install babel-cli globally:

Here’s our package.json file so you can just do npm install:

Configuring Babel

Here’s the .babelrc file I put in the same directory:

The file tells babel how to transform your code.

Transpile & Run

Once we have installed the dependencies, we can then start transpiling the codes to JS:

You might run into a problem like this:

It’s because we need to include the regenerator run time. The runtime is packed in the babel-polyfill we have already installed. We just need to include it in our source code. So the final github.es6 file would look like this:

Now if we transpile and run again, it should work fine.

নোডস্কুল – লার্নইউনোড – পর্ব ১

ভিডিও এডিটিং এ আমার অভিজ্ঞতা নেই বললেই চলে, চেষ্টা করেছি মাঝে মাঝে জুম ইন আর জুম আউট করে কোড এবং কনসোলের উপর ফোকাস করতে, কিছু কিছু ক্ষেত্রে জিনিসটা স্মুথ হয় নি, এডিটিং জনিত ত্রুটির জন্য অগ্রীম ক্ষমাপ্রার্থী