måndag 28 april 2014

Why node.js matters

Javascript is not my favorite programming language.
Even with coffeescript or sweetjs, which gives a lot of syntactic sugar to Javascript, I still prefer Ruby or Python. 
So why would I choose Javascript in the back end of a web app?

Let's start by thinking about the front end.  While it's true that you can choose whatever language you like for the back end, you really don't have a choice for the front end. If you want to build a modern web app you have to use Javascript. (Yes I know, you can use a framework like gwt where you write all of your front end code in Java, but looking at the trends it's obviously not a solution for the future)

Learning Javascript takes time. A lot of time. There are many tools and libraries available to help with various things like unit testing, minifying the code, handle older browsers and what not. Not to mention all of the different mv* frameworks, utility libraries and template engines. I've now spent a year trying to master the Javascript echo system, but I still feel I've only skimmed the surface. 

Recruiting a good programmer is hard these days. A good Javascript programmer is a lot harder. But try to find a good Javascript programmer who also have mastered your specific back end (perhaps Java + Spring MVC + Hibernate + many more)? That's almost impossible. That's the reason why a majority of the projects you see will have two separate teams: one building the front end and another one building the back end. 

Having separate teams for the front end and the back end present a whole bunch of deadline related problems. 

It's obvious during the sprint planning: some sprints will mostly be back end related tasks while the front end team more or less waits for the back end, and other sprints will be the other way around. 

Or the back end team spend time building mock ups which, even in the cases where the mock ups work fine until the real functionality is implemented, is time spent on things that will never be put into production. 

Other times two or more developers will be sick or on vacation. If both of them are on the same team it could jeopardize the deadline since you can't replace them with developers from the other team. 

If you choose Node for the back end and Javascript for the front end, you can have one team of developers, all of them jumping between different parts of the application when needed.
Do you want to know a secret?
Your front end developers already use Node. They just haven't told you about it. Go ahead and ask them if they're using Grunt. Or Bower. Or perhaps Browserify. Or npm. All of these are using Node under the hood. Your front end developers already have the tools necessary to build a Javascript application using Node, and most of them will be delighted if they can use the same tools to build your back end.

To boldly go where many men has gone before!
Go ahead and try it, and you will have one team of developers that is a lot happier, is delivering more functionality in less time and writes less lines of code.
You should have a really good reason not to choose Node for your back end!


torsdag 17 april 2014

Testing promises with Jasmine

Let's say I have this code (using lie.js for promises, but should work about the same with q.js or angulars $q):

  Foo = {bar:()->
    new Promise (resolve, reject)->
      resolve(true)
  }

If I want to test if it works, I would write a spec. To make it easier to read I will include the code under test in the spec:


describe 'Foo', () ->
  Foo = {bar:()->
    new Promise (resolve, reject)->
      resolve(true)
  }

  it 'should wait until promise resolves', () ->
    self = this

    Foo.bar()
    .then (baz)->
      baz.should.be true

I now watch it run with success:
 
Done, without errors. 

Cool, it now works. Or does it?

I change the test to something that should fail, like this;

'use strict'

describe 'Foo', () ->
  Foo = {bar:()->
    new Promise (resolve, reject)->
      resolve(true)
  }

  it 'should wait until promise resolves', () ->
    self = this

    Foo.bar()
    .then (baz)->
      true.should.be false

If we run it, it still succeeds:
 
Done, without errors. 

Obviously not quite working...
The reason is still the same, the code in the 'then' clause never executes, because the test finishes to early.

I then add a waitsFor like this:

describe 'Foo', () ->
  Foo = {bar:()->
    new Promise (resolve, reject)->
      resolve(true)
  }

  it 'should wait until promise resolves', () ->
    self = this

    waitsFor () -> self.hasRun

    Foo.bar()
    .then (aBool)->
      true.should.be false
      self.hasRun = true 
 
With the following result:
 
Done, without errors.  
 
Hmm, this is not what I expected. It should fail, right? The reason for this isn't quite obvious. Any errors in the then clause will be swallowed in the following catch clause. Which really isn't what I want. If I change to the following code:
 
describe 'Foo', () ->
  Foo = {bar:()->
    new Promise (resolve, reject)->
      resolve(true)
  }

  it 'should wait until promise resolves', () ->
    self = this

    waitsFor () -> self.hasRun

    Foo.bar().then (baz)->
          self.baz = true
          self.hasRun = true

    self.baz.should.be true

There is still the same problem with TypeError: Cannot read property 'should' of undefined 

We have to surround it with a run(), which waits until the waitsFor is complete before executing:

describe 'Foo', () ->
  Foo = {bar:()->
    new Promise (resolve, reject)->
      resolve(true)
  }

  it 'should wait until promise resolves', () ->
    self = this

    waitsFor () -> self.hasRun

    Foo.bar().then (baz)->
          self.baz = true
          self.hasRun = true

    runs () ->
      self.baz.should.equal true


Done, without errors. 

And if I change the last line to something that should fail:
      false.should.equal true
 
AssertionError: expected false to equal true 
 
So it now runs the spec as expected. And in case you don't habla coffee, here is the same test written in Javascript:
 

describe('Foo', function() {
  var Foo;
  Foo = {
    bar: function() {
      return new Promise(function(resolve, reject) {
        resolve(true);
      });
    }
  };
  it('should wait until promise resolves', function() {
    var self = this;
    waitsFor(function() {
      return self.hasRun;
    });
    Foo.bar().then(function(baz) {
      self.baz = true;
      self.hasRun = true;
    });
    runs(function() {
      self.baz.should.be(true);
    });
  });
});  

fredag 4 april 2014

What's the deal with sweet.js?

I had heard people giving praise for sweet.js, but couldn't figure out what all the buzz was about. But I decided to give it a go, and found it really good. I'm going to try to explain why I like it.

Sweet.js is quite different from Coffeescript, Typescript or Dart. These are languages that can be compiled to Javascript.

Now, Sweet.js on the other hand is not another language. In fact, after you've set up your environment to build your  Sweet.js files, you get no benefits. You still write the exact same Javascript as before. But what you get is the possibility to enhance the language.

Lets say you find yourself writing this repeatedly:

JSON.stringify(obj)

You could install a macro from npm:

npm install git+https://github.com/me97esn/conosle-macros.git --save-dev

that lets you write the following code instead:

obj as string

When sweet.js finds the above 'as string' it replaces it with JSON.stringify(obj).
But everything else is just plain Javacript.

Or let's say you would like to use the following syntax to create a range:

0 ... 10

That's totally possible. Sweet.js will replace it with
[
    0,
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10
];

See example here.

That macro is included in the above installed npm package. Just tell the sweet.js grunt task to use conosle-macros/range.sjs (or conosle-macros/macros.sjs to get all of them) and that's possible.

Just as ES6 fat arrows which allows you to write

()=>;

Instead of

function(){}

So, by installing the above macros
I can now write:
(0 ... 10).map((x)=>x *x)

Instead of writing

[
    0,
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10
].map(function (x) {
    return x * x;
}.bind(this));

Pretty neat, isn't it?

And what if you have different needs than me? Well, writing macros yourself is pretty straightforward. Just go ahead. Create some macros, publish them in npm and make the Javascript world a better place!