Step 5: Use a class as a model

Quick thoughts on differences between DartAngular and Coffeescript +
Angular:

1. Dart has a nice `isEmpty` method that checks if a string is empty. In
Coffeescript/JavaScript, I again had to use less-clear regular expressions instead.
2. Dart can have a getter & setter with the same name. This keeps the
public interface of the class pretty nice. Whereas here I keep
`$scope.name` in the public scope and make a watcher for it to
`setPirateName` when it changes, in Dart I didn't need a watcher.
The same functionality was accomplished with arguably more "standard"
programming interfaces.
3. I started to get into "fat arrow hell" here with Coffeescript. Some
of the functions didn't need access to the context's `@`, but some did.
Not a big deal, but needing to think about whether to use `=>` or `->`
is always a slightly annoying aspect of Coffeescript.

A cautionary tale about flexibility
-----------------------------------

In Dart:

    class PirateName {
      String firstName, appellation;
      PirateName([this.firstName = '', this.appellation = '']);
    }

In Coffeescript:

    class PirateName
      constructor: ->
        @firstName = ''
        @appellation = ''

When I was writing this step in Coffeescript, I was accidentally trying
to set a `lastName` attribute on my PirateName object. JavaScript just
partied on with this, which meant I did not get an error. Instead, it
just changed my PirateName object to `{ firstName: 'Jane', lastName:
'Noble', appellation: '' }`. Since I was then only displaying the
`firstName` and `appellation` attributes of this object, I ended up with
"Jane the " in my view, instead of "Jane the Noble". In this case,
tracking down the problem only took one `console.log` statement to
notice my mistake, but such errors are easily lost in much denser
code thickets during real app development.

In Dart, had I made a similar mistake, I would have gotten a helpful
stack trace telling me exactly what I did wrong:

    Class 'PirateName' has no instance setter 'lastName='.

    NoSuchMethodError : method not found: 'lastName='
    Receiver: Instance of 'PirateName'
    Arguments: ["Jackal"]

    STACKTRACE:
    #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
    #1      BadgesController.name= (http://127.0.0.1:3030/piratebadge.dart:44:9)
    #2      ...

I think flexibility is as cool as the next person, but in this case I'd
be very grateful for a programming language that fails fast, instead of
silently glossing over my errors.