Thursday, May 24, 2012

Dart Revisited

‹prev | My Chain | next›

Dart for Hipsters is making steady progress at the new publisher. It's crunch time and I need to double-check that everything still works and if there is anything new that warrants inclusion. Now that I am confident in node-spdy's spdy/3 implementation, I have some time to revisit Dart.

My copy of Dartium and the sdk are quite old so I download both. I was somewhat concerned that Dartium might not start up on my 64 bit Ubuntu 12.04 system, but I still seem to have all of the necessary system packages installed:


Since I have a working Dartium, I try pointing it at my simple dart-comics application (manages my comic book collection), which is built on top of Hipster MVC. I see the main page of the app, but nothing seems to be working. In the Dart console, I see:
Internal error: 'http://localhost:3000/scripts/HipsterCollection.dart': Error: line 100 pos 26: class 'CollectionEventList' overrides function 'add' of interface 'EventListenerList' with incompatible parameters
  CollectionEventList add(fn) {
                         ^
Hrm... The add() method in CollectionEventList accepts a single parameter—a callback function to be invoked when the event fires:
class CollectionEventList implements EventListenerList {
  // ...
  CollectionEventList add(fn) {
    listeners.add(fn);
    return this;
  }
  // ...
}
The add() method in EventListenerList requires just the callback, but it also supports an optional boolean describing whether the listener applies in capture or bubble event phases:
EventListenerList add(EventListener handler, [bool useCapture]);
Do I need type information on the callback or the optional boolean? I opt to try the latter:
class CollectionEventList implements EventListenerList {
  // ...
  CollectionEventList add(fn, [bool useCapture]) {
    listeners.add(fn);
    return this;
  }
  // ...
}
That actually does the trick as I now see my beautiful app once again:


Interestingly, the name of the optional parameter seems to be important. If I drop the "e", I still get an error:
Internal error: 'http://localhost:3000/scripts/HipsterCollection.dart': Error: line 100 pos 26: class 'CollectionEventList' overrides function 'add' of interface 'EventListenerList' with incompatible parameters
  CollectionEventList add(fn, [bool useCaptur]) {
                         ^
In effect there is more restriction on the optional parameter than there is on the required parameter. I suppose this is needed to properly support named parameters, but it did surprise me.

I am not quite done, however. When I click the "Add sweet comic" button, I get a nasty old stack trace:
Exception: NoSuchMethodException : method not found: 'get:rect'
Receiver: Instance of '_DocumentImpl@33cc944a'
Arguments: []
Stack Trace:  0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:473 col:137
 1. Function: 'ModalDialog._drawBackground@48f7d03' url: 'http://localhost:3000/scripts/ModalDialog.dart' line:75 col:25
 2. Function: 'ModalDialog.show' url: 'http://localhost:3000/scripts/ModalDialog.dart' line:38 col:20
 3. Function: 'ModalDialog.set:innerHTML' url: 'http://localhost:3000/scripts/ModalDialog.dart' line:25 col:11
 4. Function: 'AddComicForm.render' url: 'http://localhost:3000/scripts/Views.AddComicForm.dart' line:29 col:32
 5. Function: 'AddComic._toggle_form@19ec418e' url: 'http://localhost:3000/scripts/Views.AddComic.dart' line:32 col:21
 6. Function: '_EventListenerListImpl@33cc944a.function' url: '/mnt/data/b/build/slave/dartium-lucid64-inc/build/src/out/Release/obj/gen/webkit/bindings/dart/html/dartium/EventTarget.dart' line:16 col:72
The rect property used to be a property on the Document object. Now it seems to be a property of DocumentElement. So, instead of writing:
  _drawBackground([_]) {
    // ...
    window.document.rect.then((document) {
      // ...
    });
  }
Now I have to write:
  _drawBackground([_]) {
    // ...
    window.document.documentElement.rect.then((document) {
      // ...
    });
  }
The additional property feels odd, but I am not going to spend too much time worrying about it tonight. With that change in place, I again have a working Dart modal dialog:


Even better, I can save and Hipter MVC is still able to make a REST-like collection update:


That will serve for a stopping point tonight. I am pleased that everything works with just a couple of minor changes. That is pretty amazing considering how fast the language is evolving.


Day #396

No comments:

Post a Comment