Getting Jetbrains DataGrip to work with Heroku Postgres

Heroku Postgres forces you to use SSL, but the connection isn’t signed with a well-known CA. To get this to work in DataGrip, you have to mess around with some JDBC settings. Here’s how to do it:

In the add connections dialog, enter the username, password, hostname, port, and database name. You’ll have to enter these manually, because DataGrip’s URL support only works with JDBC database URLs, not the more common Postgres URLs used by Heroku.

Next, click on the Advanced tab. Then find the ssl property and set it to true. Then find the sslfactory property and set it to org.postgresql.ssl.NonValidatingFactory.

You should be good to go!

Abstract Classes with Static Methods in ES2015

ES2105 classes have much better support for static method patterns than traditional ways of doing it in ES5.

In ES2015, there are actually two prototype chains in classes: one for instance methods and one for static methods. This means you can use super and this in a static method, and it works as expected.

This makes using an abstract class pattern much easier. Here’s an example:

'use strict';

class AbstractShape {
  static get SHAPE_NAME() { throw new Error('must specify a SHAPE_NAME in your subclass of AbstractShape'); }

  static get englishName() {
    return this.SHAPE_NAME['en-US'];
  }

  static get spanishName() {
    return this.SHAPE_NAME['en-MX'];
  }
}

class Square extends AbstractShape {
  static get SHAPE_NAME() {
    return {
      'en-US': 'square',
      'es-MX': 'cuadrado'
    }
  }
}

console.log(Square.englishName); // -> 'square'
console.log(Square.spanishName); // -> 'cuadrado'
console.log(AbstractShape.englishName); // Throws an Error

A few things that are interesting with ES2015 static methods:

  • You can’t have static properties, but you can make static getters to get the same effect (with some syntactic noise).
  • In a static method, this refers to the class itself. Effectively, you can just access other static methods with this.
  • You cannot refer to the class itself in the class body. This is not legal:
static get englishName() { return AbstractShape.SHAPE_NAME['en-US']; }

I’m guessing is the reason for this is that classes are not hoisted in ES2015.

More class posts coming soon!

Refactoring an Existing NodeJS App for ES2015 (Part 1)

Thinking of getting started with ES2015? Coding with NodeJS v5.0.0 or higher? You can get started today! Node supports many features of ES2015 natively, without the need for a transpiler like Babel or Traceur.

ES2015 actually has a lot of really awesome features, and I think most of them are worthwhile to start using eventually. But, it you already have a Node app written and want to introduce ES2015 gradually, which features should you pick first?

This post talks about the three ES2015 features that I would focus on first. I picked these because they are the most compatible with existing patterns and are the easiest for developers to pick up and start using right away. They are also all supported fully in Node 5.x.

The features are:

  1. Block-scoped declarations (let and const)
  2. Arrow functions
  3. Template strings and new String methods

Part 2 will of this series will talk about classes.

Start using block-scoped variable declarations (let and const) instead of var

Note: You need to be in strict mode ('use strict') for these keywords to work. If you are using the Node REPL, you need to start it with node --use_strict as opposed to typing 'use strict'; within the REPL.

What is this let business?

The var keyword has a few issues that have been corrected by the new let keyword. First of all, var may be hoisted like this:

bla = 2; 
var bla;

// is identical to:
var bla;
bla = 2;

Second of all, var-defined variables have the scope of entire enclosing function.

function varExample() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

The let keyword avoids all of this weirdness. When you use let there is no hoisting, so you will get a ReferenceError at runtime:

function a() {
   c = 1;
   let c = 2;
   return c;
}
a(); // ReferenceError: c is not defined

Variables declared with let are block-scoped, not function scoped. A block is any section of code delimited with { ... }. Here’s an example:

let x = 1;
let y = 2;
if (y > x) {
  let a = 3;
  x = a;
}
console.log(x); // 3
console.log(y); // 2
console.log(a); // ReferenceError: a is not defined.

What about const?

The const keyword follows the same scoping and (non-) hoisting rules as let. It has one more constraint, though: variables declared with const don’t change their reference.

Here’s a few examples:

const A = 1;
A = 2;   // TypeError: assignment to a constant variable

It’s also important to realize that const doesn’t enforce immutability for objects. You can change object properties of objects declared with const:

'use strict';
const MY_OBJECT = {
   MyProp: 1
};
MY_OBJECT.MyProp = 2; // no error here!
console.log(MY_OBJECT.MyProp); // 2

Refactoring recommendation

If it is possible to use const, use it. If it isn’t possible to use const, use let. Don’t use var anymore, unless you find some crazy edge-case where it is necessary.

Arrow functions

Arrow functions are a shorthand for writing small, anonymous functions. They also adopt the scope of their surrounding code, rather than creating a new one. This can eliminate use of the var self = this; pattern, and eliminate some uses of .bind().

Arrow functions also have a further-shortened version for implicitly returning the value of an expression. This is great for iterators and lodash-style functional programming.

Here are some examples:

let myArray = [1, 2, 3];
// These are all equivalent:
myArray.map(function(i) { return i + 1; })
myArray.map((i) => { return i + 1; });
myArray.map((i) => { i + 1; });
myArray.map((i) => (i + 1));
myArray.map((i) => i + 1); // expression (i + 1) must be on one line
myArray.map(i => i + 1); // also must be on one line
// all return [2, 3, 4]

Here’s an example of the way this works with arrow functions:

function Person () {
   this.age = 0;
   setInterval(function() { this.age++; }, 1000);
}
let p = new Person();
p.age; // -> 0
// (wait a few seconds)
p.age; // -> still 0

You could fix this with self, but that is annoying. Arrow functions make this easier:

function Person() {
   this.age = 0;
   setInterval(() => { this.age++; }, 1000);
}
let p = new Person();
// (wait a few seconds)
p.age // -> not zero

There are a few other differences with arrow functions that are more obscure:

  • Within the arrow function, arguments refers to the surrounding function, not to the argument list of the arrow function.
  • .call(), .bind(), and .apply() cannot change the scope of an arrow function. They still work otherwise (and have the same function signatures themselves). If you use them, this within the arrow function will just be unchanged.

Refactoring recommendation

Use arrow functions extensively. They are way better. One important thing to note, however, is that you still must use the anonymous-function syntax for method declarations:

let MyClass = BaseClass.extend({ 
   myMethod: function() { 
      return 'the return'; 
   } 
});

Template strings

Template strings are common in other programming languages (Like PHP, Python, and Ruby). They let you avoid code like this, which is extremely prone to errors and typos:

let now = month + ' ' + day + ', ' + year + ' ' + hour + ':' + minute;

With template strings you can write:

let now = `${month} ${day}, ${year} ${hour}:${minute}`;

Template strings start and end with backticks (`). You can put any expression within the templates:

let a = 2;
let myString = `2 plus ${a} is ${2 + a}`;
// -> "2 plus 2 is 4"

Template strings can also be multi-line:

let myString = `This is a
multi-line string`;
// -> "This is a\nmulti-line string"

Refactoring recommendation

Use template strings in most cases where you would normally use string concatenation. Definitely use template strings for multi-line strings. They are particularly useful for inline templates in Angular directives.

New String methods

The String class has a few new useful methods. The most useful ones are:

  • haystack.includes(needle) – tests if a haystack includes needle. No more haystack.indexOf(needle)!
  • haystack.startsWith(needle) and haystack.endsWith(needle) – self explanatory.
  • 'test '.repeat(3) – returns 'test test test '.

Refactoring recommendation

Definitely use these methods instead of indexOf() for checking for substrings. They are much more readable.

How to Create an EEG Spectrogram with Python

I recently got a Neurosky Mindwave, which measures EEG waves and sends them via Bluetooth to your computer or phone.

Busting out some of my rusty signal processing from college, I made a spectrogram from the EEG. Check it out!

EEG Spectrogram
EEG Spectrogram from Mindwave Mobile

To check out how I made this, see this IPython notebook. This is using Jupyter and Python 3, with data recorded using node-thinkgear-sockets.

How to Parse Sketch Files with NodeJS

I’ve recently been working more with Sketch, and wanted to see if I could get Sketch files to render on Linux. Turns out that no one has released open-source software to parse or open Sketch files yet, so I decided to see how hard it would be to parse them with NodeJS.

Here’s the results of my efforts: Github Project

This needs more work to make it usable, but Sketch files aren’t too difficult to deal with.

Two Resources to Learn About Copywriting

  1. The Google Material Design Guidelines for Writing. The whole Material Design style guide is a good read to learn about UX, but the writing section is excellent to learn about writing clear, concise copy for user interface.

  2. Key Questions to Ask Before Writing & Before Testing Advertising Copy. This article has an excellent description of the difference between inductive and deductive writing strategies. When technical experts write, they typically do so in a deductive way, leading the reader through a logic argument that culminates in the conclusion. That might not work well for advertising copy, and this article explains why.

Where Should I Host My Single Page App?

If you are working on an MVP web app these days, chances are you are using a single page app (SPA) framework like Angular, React, or EmberJS. These frameworks are great for a lot of reasons, one being that you can typically host the front-end with just a static file webserver like NGINX or Apache.

Maintaining a webserver is still probably not the best use of your time when you are trying to get your MVP out the door, and hosting a SPA is a little more complex than just a static HTML site. There are a lot of shortcuts out there (such as using Amazon S3) and a few hosted platforms are emerging. Read on to see a comparison of the current solutions, and leave a comment if you know of any others!

Amazon S3 + Cloudfront
Ease of deployment Can be made to work well with grunt/gulp plugins
Avoids writing or maintaining a webserver Yes
Serves files using a CDN Yes
SSL on your own domain Yes
Supports pre-rendering for bots No
HTML5 pushState support Sorta, by making index.html the default 404 error page
Proxies backend to avoid CORS issues No
Price for a basic, production site Depends on traffic, but very cheap
Amazon S3 + MaxCDN
Ease of deployment Can be made to work well with grunt/gulp plugins
Avoids writing or maintaining a webserver Yes
Serves files using a CDN Yes
SSL on your own domain Yes
Supports pre-rendering for bots Not really. Possible to make Googlebot work with EdgeRules.
HTML5 pushState support Yes, and can fix 404 issue with EdgeRules.
Proxies backend to avoid CORS issues No
Price for a basic, production site $15/month + S3 charges (minimal). Call for EdgeRules pricing.
Firebase Hosting
Ease of deployment Has it’s own deployment tools that support immutable deploys and rollbacks
Avoids writing or maintaining a webserver Yes
Serves files using a CDN Yes
SSL on your own domain Yes
Supports pre-rendering for bots No
HTML5 pushState support Yes
Proxies backend to avoid CORS issues No
Price for a basic, production site $5/month
Aerobatic
Ease of deployment Easy, git-push deploy using Bitbucket
Avoids writing or maintaining a webserver Yes
Serves files using a CDN Yes
SSL on your own domain Yes
Supports pre-rendering for bots No
HTML5 pushState support Yes
Proxies backend to avoid CORS issues Yes
Price for a basic, production site $10/month for 5 sites
Custom Server on Heroku
Ease of deployment Easy, git-push deploy
Avoids writing or maintaining a webserver No
Serves files using a CDN No
SSL on your own domain Yes
Supports pre-rendering for bots Possible
HTML5 pushState support Possible
Proxies backend to avoid CORS issues Possible
Price for a basic, production site $25/month + $20/month for SSL
Custom Server on Heroku + CloudFront
Ease of deployment Easy, git-push deploy
Avoids writing or maintaining a webserver No
Serves files using a CDN Yes
SSL on your own domain Yes
Supports pre-rendering for bots Potentially possible by adjusting caching based on User-Agent
HTML5 pushState support Possible
Proxies backend to avoid CORS issues Possible
Price for a basic, production site $25/month + traffic-based charges for CloudFront (very cheap)
Custom Server on Heroku + CloudFront
Ease of deployment Easy, git-push deploy
Avoids writing or maintaining a webserver No
Serves files using a CDN Yes
SSL on your own domain Yes
Supports pre-rendering for bots Possible with EdgeRules
HTML5 pushState support Possible
Proxies backend to avoid CORS issues Possible
Price for a basic, production site $25/month + MaxCDN charges (see Amazon + MaxCDN section)

So what’s my recommendation? If don’t need your app to be indexed on Google, show previews on Facebook’s Open Graph, or show cards on Twitter, both Firebase Hosting and Aerobatic are good options. In theory, Googlebot is starting to crawl SPAs, but in practice I have not had good luck with that. The other crawlers seem to be far behind Google, so you’ll likely need pre-rendered pages, anyway.

If you do need to support bots by serving pre-rendered HTML, you are unfortunately at a real loss. I think your best option in that case is to host your front-end on Heroku (using NGINX, Express, Hapi, or some other simple server), and use a service like Prerender.io to serve pre-rendered HTML to bots. See here for how you would set up Prerender.io using NGINX. Alternatively, you can let the Firebase Hosting guys know that you really want pre-rendering support in this PR.

How much space does Postgres’s new JSONB format save?

Postgres 9.4 has a new column format called “JSONB” that is a binary representation of JSON. The coolest thing about this new column type is that it supports indexes, so you can now query JSON columns much faster. However, a side benefit is that it is also slightly smaller. I recently did a test where I took a 53 MB table of mostly JSON data and converted it to JSONB. Before and after the conversion I did a VACUUM FULL on the table. Space savings was about 12.3%.

Just one observation you might want to consider if you are thinking about switching formats.

Export a Heroku Postgres Schema

This is a quick script to export just the schema from a Heroku Postgres database. It exports the schema with no ownership information, so you can easily load it into a local database.

#!/usr/bin/env ruby
require 'uri'
db = URI(`heroku config:get DATABASE_URL`)
system("export PGPASSWORD=#{db.password}; " +
       "pg_dump --schema-only -h #{db.host} -p #{db.port} " +
       "-U #{db.user} -d #{db.path.gsub('/','')} --no-owner -f schema.sql")

Make sure you run this script from a folder within your app (with the Heroku git remote correctly set up). It will put the schema in schema.sql in the current working directory.

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.