Monday, May 18, 2015

Preparing for Polymer 1.0 - hangout-app

It must have been shortly after the Chrome Dev Summit in 2013 that I first started looking into Polymer. A lot has changed since then and most of the code I had written for the early versions of Polymer looks completely different now and went through a lot of re-write stages, but that's what you get for living on the bleeding edge ☺

Now Polymer has reached beta state with the 0.9 release and 1.0 is expected to come out at I/O so the time of breaking changes is slowly coming to an end. Some of my projects will probably forever remain like they are now, but I thought it was about time to start updating some of my more important (imho) elements, starting with my <hangout-app> element, that makes developing Hangout Apps easier.

While migration is generally easy thanks to migration guide there are still some things I've stumbled over (mostly because I flipped through the migration guide too quickly...)

No inheritance from custom elements (for now)

When I first created this element I had the idea (which seemed brilliant and completely logical at the time) to let people inherit from the hangout-app element to create their own hangout apps, so they could depend on the loaded property of the parent element to know when the Hangouts API is ready to be used:
With inheritance from custom elements not being supported (for now) I had to rethink this idea and I think the new solution is actually much clearer. You can now include the hangout-app element anywhere in your project and either wait for its ready event to fire or bind to its loaded property. Alternatively you can also include any of your markup as content of the hangout-app element and this content won't be rendered until the Hangouts API is ready to be used.

Conditional templates

The old <template if="{{condition}}">...</template> implementation removed/added DOM elements completely when the condition changed, which could have a negative effect on performance if used excessively, and I have to admit that I used it way too much in my projects, simply because it was easy to use and made the code somewhat clearer.

As I wrote a while ago the much better solution in most cases is to simply hide/show by conditional attribute binding to the hidden attribute: <div hidden$="[[!condition]]">...</div>

In the case of the hangout-app element I wanted to make sure that none of the content that might depend on the Hangouts API is part of the DOM until the API is ready, e.g. when using the hangout-shared-state element which tries to called the Hangouts API as soon as it is attached. For that reason I used the new implementation of conditional templates in the form of dom-if.
<template is="dom-if" if="[[loaded]]">
  <content></content>
</template>
This new implementation by default adds the content the first time the condition becomes true and afterwards only shows/hides the elements as necessary.

Layout attributes > Layout classes

I completely missed this part of the migration guide and was very surprised when my layout didn't look the way I expected it to.

The change from attributes to classes is easy enough though, just make sure to include PolymerElements/iron-flex-layout in your dependencies.


That's it for now, more coming as I upgrade more of my elements ☺