Monday, December 2, 2013

Converting Polymer Elements to Dart

GitHub reports that Patterns in Polymer is 59% JavaScript and 17% Dart. I am trying hard not to favor Dart too obviously and Dart dependencies do not make nearly the mess that their JavaScript counterparts do. Still, I need to keep up with the Dart version of the book, so tonight, I am going to get my change-history Polymer element re-written in Polymer.dart. If I am still feeling ambitious, I will swap out the <polymer-localstorage> element for <polymer-ajax>

Happily, this is Dart, so getting started is far easier. I create a pubspec.yaml file with my dependencies (Polymer and Polymer Elements):
name: change_history
  polymer: any
  unittest: any
The git dependency is necessary because the most recent version published to Pub depends on a pre Dart 1.0 SDK. Hopefully the Git repository is not too bleeding edge (polymer-localstorage and polymer-ajax were both listed as ported in the versions on Pub).

After a quick pub get, I am ready to go.

My first stop is web/index.html. I copy the JavaScript version directly and make the following Dart changes in the <head> of the document:
    <!-- Load component(s) -->
    <link rel="import" href="/packages/change_history/change-sink.html">
    <link rel="import" href="/packages/change_history/store-changes.html">
    <link rel="import" href="/packages/polymer_elements/polymer_localstorage/polymer_localstorage.html">

    <script type="application/dart">export 'package:polymer/init.dart';</script>
    <script src="packages/browser/dart.js"></script>
The underscore and extra patch in polymer_localstorage/polymer_localstorage.html were unexpected. That aside, everything goes smoothly… until I try to re-implement the enteredView() handling from JavaScript. For instance, if I define the <change-sink> element as:
<polymer-element name="change-sink" attributes="was current child">
  <script type="application/dart" src="change_sink.dart"></script>
And add a corresponding change_sink.dart as:
import 'package:polymer/polymer.dart';
import 'dart:html';

class ChangeSinkElement extends PolymerElement {
  @observable String was ='';
  @observable String current = '';
  @observable Element child = null;
  ChangeSinkElement.created(): super.created() {
    style.backgroundColor = 'red';
  ChangeSinkElement.enteredView() : super.enteredViw() {
    style.backgroundColor = 'green';
Then I see the style change from the create() lifecycle event, but not the same change from the enteredView(). Instead of green, the background color remains red:

It takes me far too long to realize that I have simply cargo coded enteredView() here. I am defining a named constructor ChangeSinkElement.enteredView() instead of a enteredView() method. It really bother me that I can make obvious mistakes like that. Happily, once found, the fix is easy enough—convert it to a method:
  // ...
  enteredView() {
    child = children[0];

  // ...
Once I make it through silly things like that, the rest of the conversions goes smoothly. Unfortunately, messing around with <polymer-ajax> will have to wait until tomorrow.

Day #953

No comments:

Post a Comment