Friday Links

  • Music I’m rocking out toTwo Hearts by The Features and Firestone by Kygo.
  • Interesting read — The NYTimes has a great article praising the Fox News coverage of the Republican debate. I agree with it, the Fox moderators were almost Jon Stewart-esque!
  • Tools and tech — I’ve been experimenting with different development environments for NodeJS, and the winner so far is JetBrain’s WebStorm. Code completion support is excellent, and the integrated Node debugger is a huge time saver. At $49, it’s a no-brainer if you do any kind of Javascript development.

Google Analytics with AngularJS and UI-Router

I helped Clean Slate DC add Google Analytics to their app last night at Code For DC and realized others might not know how to do this. It’s pretty simple, but you won’t want to follow the directions on Google Analytics exactly. Instead, add this to your index.html or main page <head>, replacing your UA code with the UA code that Google gives you:

<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXX-X', 'auto');
</script>
<!-- End Google Analytics -->

Next, add a service to your Angular project:

angular.module("app").service('Analytics', function() {

  this.recordPageview = function(url) {
    ga('set', 'page', url);
    ga('send', 'pageview');
  };

});

Finally, add a run block near where your app starts:

angular.module("app").run(function($rootScope, $location, Analytics) {
  $rootScope.$on('$stateChangeSuccess', function() {
    Analytics.recordPageview($location.url());
  });
});

There you go!

Fixing SyntaxHighlighter Evolved Font Size

SyntaxHighlighter Evolved is currently the plugin I use for syntax highlighting on this site. It uses the default text size for code blocks, which doesn’t look great since code is in a fixed-width font. To fix that, add a class to the code blocks called code-blk in Settings > SyntaxHighlighter. Then modify your theme’s CSS (or use the WordPress Jetpack Custom CSS feature) to add CSS like this:

.code-blk {
   font-size: 10pt !important;
}

Thanks to this post for the inspiration.

Gotchas with Hapi’s Code Library

Overall, I’ve had a good experience with HapiJS and Code, Hapi’s assertion library. There was one gotcha with Code’s deep.equal function. If you are comparing two objects that have identical non-function properties, but different function properties, deep.equal will fail. So, for example, if you compare a Hapi response to a Plain Old Javascript Object fixture, you will get an exception.

The solution is to strip the non-function properties before comparing:

// response - an object with some function properties
// fixture - a Plain Old Javascript Object
var responsePojo = JSON.parse(JSON.stringify(response));

expect(responsePojo).to.deep.equal(fixture);

NodeJS and Hapi for Rails Developers

This post is an work in progress list of tips and tricks I’ve learned working on a HapiJS API after mostly coding Rails APIs for the last few years. I expect to update it as I learn more.

If you are a Rails developer looking to transition to NodeJS, hopefully this will save you some time. If you are a more seasoned NodeJS or Hapi developer and have suggestions for improving this, please let me know in the comments.

Async Programming

Error-first callbacks, promises, or async/await

Most Rails developers have written some Javascript, so you are probably familiar with callbacks. On the client, having nested callbacks is relatively rare. On the server, however, they are far more common. A simple example would be a server method that needs to make a handful of database calls, with all of the depending on the outcome of the others. This would be trivial to write in a sequential way, but with NodeJS, you will need to nest callbacks to accomplish the same thing.

This is both the best thing about NodeJS and the most annoying. It makes things very performant, because with callbacks you continually return control to the main event loop, freeing the main thread to move on to other things. In Rails, unless you are using a threaded server like Puma, waiting on a database call will block the entire process.

All of Node core and most of the libraries use error-first callbacks. If the first argument to the callback function is truthy, then you know the callback has failed with an error. You’ll see a lot of code in NodeJS like this:

var myCallbackFunction = function(options, function(err, result) {
   if(err) return err;
   // process the result
});

This gets nasty when you have many nested callbacks and has been dubbed “callback hell”.

One way to fix this is to use a promise. You can typically turn any error-first callback function into a promise-returning function with Promise.promisify().

var Promise = require('bluebird'); // bluebird is a popular promise library
var myAsyncFunction = Promise.promisify(myCallbackFunction);

myAsyncFunction(options).then(function(result) {
   // process result
}).catch(function(err) {
   // process error
});

This doesn’t look Earth-shattering, but promises can make deeply nested callbacks more readable. I like promises from my AngularJS programming, but they aren’t widely used in the Node community. If you attempt to use them, you feel like you are fighting an uphill battle since everyone still uses error-first callbacks. They can be vital in some situations, however.

ES7 and async/await

The next generation of Javascript will hopefully solve all of our problems with the addition of two new keywords: async and await. These use promises under the hood, but you can use trycatch and don’t need then():

try {
   var result = await myAsyncFunction(options);
   // process result
} catch (ex) {
   // handle error
}

You can use this today if you transpile with the Traceur compiler, but not much of the Node community is doing that yet. Once more people get on board, this will be a huge improvement in Javascript.

What do do today?

Today, I think you should stick with error-first callbacks and use promises if absolutely necessary. Another library you can look into is the async library, which gives you lots of nice functions to handle many callbacks in series or parallel.

Unit Testing

NPM packages to use

  • Lab – Hapi’s unit testing framework. It supports both TestUnit and RSpec style tests. I’m using the RSpec style.
  • Code – An assertion library. This handles expect statements. There are a few gotchas.

Test folder setup

I’m using RSpec style tests, so my folder hierarchy looks like this:

+ /
|
+---specs
|
+---requests
| |
| +---users
| |
| +---get.js
|
+---models
|
+---user.js

Running your specs

To run your specs, you have two choices. You can either install lab globally and run them with the lab command, or you can change your package.json file to set what to run for npm test. I usually do the second options, because it lets me specify some default options for lab. Here’s what the section of package.json file looks like:

{
   "scripts": {
      "test": "env $(cat .env | xargs) lab -v -L -m 0"
   }
}

The xargs part is to set the environmental variables before running the tests from the .env file. There probably is a better way to do this, but that is working for now.

Getting Node-Inspector to work with Lab/HapiJS

Debugging specs with console.log statements is a real pain. Node-Inspector is far better, giving you an environment that is basically the same as Chrome DevTools.

To use it with Lab, add this script to your package.json file:

{
  // other package.json stuff
  "scripts": {
    "test-debug": "node-debug ./node_modules/.bin/lab"
  }
}

You can now run all of your specs with npm run test-debug , or run the specs in just one file with npm run test-debug <path to your spec file>.js .

Reactive UI Reading List

These are just a few articles to read about Reactive UIs on OSX. The more I read about it, the more functional, declarative UIs seem like the way forward.

  • ComponentKit is like React Native, but in Objective C++. Someone ported it to OS X! But you cannot use it with Swift, yet.
  • Pure UI – the merits of React as a programming model.
  • Few.swift – Similar to ComponentKit, but in Swift. Not used in production yet.

Using Node datapipes to ETL from one MongoDB collection to a second MongoDB collection

ETL – not the most fun to write, but the datapipes package makes it pretty easy on NodeJS.

One thing that wasn’t explained in the documentation well was how to ETL from one MongoDB to another using the MongodbMixin. The problem when you use the MongodbMixin twice in the same pipe is that it gets confused about which connection to use for which things. Here’s how to use pipe groups to fix that.

var etlProcess = datapumps.group();

var extractPump = etlProcess.addPump('extract')
extractPump
  .mixin(MongodbMixin(sourceDbUrl))
  .useCollection(sourceCollection)
  .from(extractPump.find({})); // take all items from sourceCollection

var upsertPump = etlProcess.addPump('upsert');
upsertPump
  .from(extractPump)
  .mixin(MongodbMixin(sinkDbUrl))
  .useCollection(sinkDbCollection)
  .process(function(item) {
    console.log(' - ETLing ' + item['_id']);
    // need to return a promise from process
    return upsertPump.update({ '_id': item['_id'] }, item, {upsert: true});
  });


etlProcess
  .logErrorsToConsole()
  .start()
  .whenFinished().then(function() {
    console.log('finished ETLing.');
    process.exit(0);
  });