Bojan Gvozderac

Polymer — Tonnes of Potential! Not Quite There… YET

Yes. It’s another web app framework that you need to consider, and this post will tell you why you’ll consider it for your next web app project.
Yes, yes, I know, I know… you have your Angulars and your Reacts and your Vues and your [insert framework name here]'s so why would you want to even think about a new web app framework, let alone use one?!

Hear me out buddy boy!

What if I told you there’s a web app framework out there that can help you reason with your UI better, that is TRULY component based and that in this framework you create self-sufficient, independent and reusable components. Would you use a framework like that?
No? Still not convinced? Let’s continue then.
This framework I’m talking about doesn’t just build web apps, it builds Progressive Web Apps (Link)!
That means those apps:
  • Look and behave like native apps
  • Use techniques like App Shell and enhanced caching, or to put it more plainly the app loads almost instantaneously on repeat visits
  • Can work offline without an internet connection
  • Boost user engagement by utilizing push notifications
  • I think I have your attention… let me introduce you to Polymer (Link)!
    If you want to know more about Polymers mission and philosophy you can check out it’s About page (Link). I’ll just leave you with this.

    Developers deserve a platform they can work with, not around.

    Ok, wait wait wait, the title says Polymer is “not quite there yet” and now I make it sound like it’s the best thing since JavaScript (Link and shameless plug). So, what’s going on here?!
    Well, what Polymer does is one thing and working with Polymer is a whole different thing…

    The Process

    Whenever I want to see what working in a web app framework is like I dream up a really simple project that could (in a very basic way) be considered an minimum viable product and incorporate common actions such as events, reacting to events, manipulating the DOM etc.
    And that’s how “PuppIMDB” was born!
    PuppIMDB is a web app that lists ALL (10) puppy shows in the world!
    Want puppy drama? No problem.
    Puppy comedy? Sure thing!
    Puppy based crime shows? Weird, but we got those as well.

    Let’s Start Building the App!

    You can find all of the code for this app on my Github (Link)

    First things first, I need to initialize the app and I’ll be using polymer-cli (Link) to do it. Polymer-cli is a command line tool that helps developers get started with new Polymer projects by creating the base folders and files needed for Polymer to work. After I’ve done that I use polymer serve in the terminal to serve the newly created Polymer app ( you can find all the steps for initializing a Polymer app here — Link).

    index.html

    Let’s look at the entry point for our app — index.html
    Nothing out of the ordinary here except for the script tag with webcomponents-loader.js, link with rel=”import” and href that targets a html file (what?) and the <pup-app></pup-app> tag.
    and href that targets a html file (what?) and the <pup-app></pup-app> tag.

    Notice the <body style="margin: 0;">!
    That is my hyper-advanced css reset. You’re welcome.

    Let’s go through the list one by one.
    Webcomponents-loader is a loader for webcomponent polyfills (Link). Next up is the ‘import’ link. In Polymer we import components that have everything necessary for them (markup, CSS and JavaScript) in one html file and when we want to use that component somewhere we import that html file, pretty straight forward right?
    Lastly we have <pup-app></pup-app>. If you paid close attention you’ll notice that we imported pup-app.html with our link rel=”import” tag and, you guessed it, <pup-app></pup-app> is our custom component that holds our app.

    Main App component

    Now we’re getting to the fun stuff! Let’s see what the finished pup-app component code looks like.
    Lots of new and fun stuff here! There’s lots to cover here so lets get started!
    I would have skipped the imports since we talked about them already but there’s one thing there that fcked with me REAL bad:

    <!-- This bastard -->
    <link rel="import" href="../../bower_components/polymer/lib/elements/dom-repeat.html">


    The dom-repeat import incident

    As you would expect like many frameworks Polymer also has a way of creating DOM elements by iterating over an array of values ( dom-repeat ) but what the documentation glances over rather than highlight is that you need to import dom-repeat component to make it work, and here we get a taste of Polymers biggest weakness — error logging or rather LACK OF proper error logging.
    When I typed in the dom-repeat code and refreshed the app nothing happened, elements didn’t render and I was getting no error and so the search began.
    I did what every coder does at this point, I google it!
    Aaaaaand… nothing again, just Polymer 1 documentation and old stackoverflow links… You see, Polymer just migrated from version 1 to 2.0 and trying to find a relevant answer is 3.5 hours of exhausting work (admittedly, this is temporary and in time relevant answers will start to appear on first pages of search results).
    What was even more baffling is that I had another Polymer codebase from earlier where dom-repeat was working just fine, I spent an hour and a half looking at the 2 codebases trying to figure out what was different.
    I eventually found the dom-repeat import difference but here’s the kicker… The dom-repeat wasn’t imported in the file using it but another file that was imported into the file that uses dom-repeat, this felt weird and a bit wrong!

    CSS Variables

    Not exactly Polymer but still pretty cool are CSS variables (Link)
    1:host {
    2display: block;
    3height: 100%;
    4background-color: #efefef;
    5--app-font-family: 'Montserrat', sans-serif;
    6--color-burlywood: burlywood;
    7}
    8
    You define CSS values for your variables and then you’re free to use them anywhere they’re available. Like so font-family: var(--app-font-family) neat!

    The Syntax

    Polymers syntax for passing data to components, handling events etc. feels strange at first but you get used to it pretty fast and it’s nothing special so we’ll just run through it quickly.
    1<pup-details
    2 show={{showDetails}}
    3 on-close-modal-click="_closeModalHandler"
    4 class$="{{_displayDetails(displayDetails)}}">;
    5<pup-details>
    6
    pup-details is a modal window that displays details of the puppy based show you selected.
    We pass the show that was selected with show={{showDetails}}. showDetails is a variable that holds the selected show object and ‘show’ is the property inside the modal where the selected show is stored.
    As you can see, pretty standard web app framework syntax.

    Polymer has two way data binding with {{}} syntax and one way data binding syntax [[ ]].
    On small projects such as mine it doesn’t matter which one you use but reading through a few other Polymer articles it appears that on larger projects choosing the right data binding method becomes really important.

    on-close-modal-click=”_closeModalHandler” isn’t built in but rather a custom event which is dispatched inside the modal and registered in the modal parent with on-<custom event name>
    This is actually pretty cool and feels clean and terse.

    Polymer doesn’t allow passing data to event handlers which is beyond stupid to me.
    It’s one of those things that you don’t appreciate until it’s taken away from you and it makes zero sense to me to not allow this feature. I just hope the Polymer team comes to their senses and implements this feature some time in the future.

    class$={{_displayDetails(displayDetails)}} isn’t anything too special the $ sign (other than being ugly to look) just tells Polymer to bind to the DOM element attribute and not to the Polymer element.

    Notice how we can pass data to a function in this case.


    The JavaScript

    Now for my favorite part, JavaScript!

    I’m not going through the entire JS code here just the interesting parts as most of it is simple and straight forward.

    1static get properties() {
    2 return {
    3 appName: {
    4 type: String,
    5 value: 'PuppIMDB'
    6 },
    7 showList: {
    8 type: Array,
    9 value() { return []; }
    10 },
    11 displayDetails: {
    12 type: Boolean,
    13 value: false
    14 },
    15 showDetails: {
    16 type: Object,
    17 value: {
    18 name: '',
    19 genres: []
    20 }
    21 }
    22 };
    23}
    24
    This is how you define what properties are available to a Polymer element and I REALLY like this approach. Just by looking at the code I know exactly what properties this element expects to have. NICE!
    connectedCallback() is Polymers version of onComponentDidMount from React or ngOnInit from Angular 2. Translation: when component is done initializing run this code.

    The dom-repeat Nondescript error incident

    Here I had some real ‘fun’!
    When you include these lifecycle hooks inside your custom element classes you need to call the appropriate ‘super’ functions, this is all fine and great and fairly common but you can’t just do super() and be done with it, you need to call the appropriate super<lifecycle-hook-function-name>() for it to work and if you don’t the element won’t work or if you try to run some code inside it you’ll get some funky internal Polymer errors.
    In my case I tried assigning a value to an array and I’d get this totally nondescript error from which I can’t get ANY information on what the possible solution can be. Completely useless.
    Same Error Different Place and Context

    I won’t go over all components as they don’t do anything new or different from the main component, I’ll just mention certain scenarios and situations I experienced while working on these components.
    You can find the code on my Gihub (Link, again)

    Sadly, the only thing worth mentioning when talking about the other components is the terrible error logging… In pup-details component we needed to print a value in a <span> from an array and since you can’t do something like this {{ someArray[0] }} in Polymer, I had to use this approach [[_printShowGenre(show)]] and here’s the function printShowGenre(show) { return show.genres[0] || 'N/A'; }
    Here we hit another wall of error logging frustration.
    When I first wrote the above function I wrote genre instead of genreS and Polymer threw the exact same error as the one above!
    This is a major problem because it’s the same error but the context and solution is totally different, the only thing they had in common is that the issue is somehow related to arrays.
    In the case of genres[0] it should have printed out that I was trying to access a nonexistent property and not some internal binding error bullshit, you know, like every other framework out there!
    In the case of connectedCallback() the error logging is especially terrible because it is totally misleading. The problem wasn’t with the array but with me not calling super() correctly, it should be connectedCallback() { super.connectedCallback() } and not connectedCallback() { super() } which is what I did.

    The interesting bits

    There are a few things about Polymer that I can’t decide if they’re right or wrong but they’re definitely interesting.
    Custom Events
    In Polymer you can define custom events that components can subscribe to ( think event emitter ), let’s look at an example from our app.
    In pup-details we have a close modal button that looks like this:
    <button class="close-button" on-click="_closeModal">Close</button>
    and the JS:
    _closeModal(){this.dispatchEvent(new CustomEvent('close-modal-click'))}
    In pup-app we subscribe to it like this ( notice the on-close-modal-click ):
    1<pup-details
    2 show={{showDetails}}
    3 on-close-modal-click="_closeModalHandler"
    4 class$="{{_displayDetails(displayDetails)}}">
    5</pup-details>
    6
    _closeModalHandler contains code that runs when close-modal-click is dispatched. Simple.
    There’s nothing special going on here but in Polymers case this approach of handling events feels right and really fun! I didn’t get this from other frameworks even though you can implement similar ( or even exact same ) functionality.
    Services
    In most apps developers abstract away certain logic (usually some kind of calculation) into ‘Service’ files.
    For example, you get some data from your API and you want to transform it in some way before displaying it. Instead of your apps view layer doing the data transformation (calculation) you abstract away it into the ‘Service’ file and the view layer calls the ‘Service’ file to get the already prepared data ready for displaying. This way your view layer is only responsible for displaying data (as it should be) and not transforming the data or doing calculations on the dataset.
    In most frameworks you just create a .js file write the service logic in it and import (Link) it where you need it, in Polymer it’s a little bit different.
    Polymer only allows importing .html files and the ‘workaround’ goes like this: you create a .html file put a <script></script> tag inside it and in it you write the service logic. This feels really wrong on a number of levels and it seems the ‘Polymer way’ is to have the component contain all markup, style AND logic it needs inside itself. Which makes sense when you consider Polymers aim is to create components that you can place anywhere and they just work.
    Polymer IDE
    My IDE of choice is VS Code (Link) and it has an extension that you can install called ‘Polymer IDE’. Polymer IDE is supposed to help you develop Polymer apps by offering autocomplete suggestions, underline bad imports etc. while it does help with suggestions and underlining most of the time, sometimes it just refuses to work so there’s that. Currently Polymer IDE’s version is listed as 0.5, I’m hoping all of these issues are fixed when it gets a proper 1.0 release. I imagine this will make developing Polymer apps much, much easier.
    webcomponents.org
    It’s important to mention webcomponents.org (Link, so you don’t need to copy + paste) you can find all sorts of custom components to save you the trouble, effort and time of building everything from scratch.
    It has some pretty cool stuff that can speed up your project development significantly!

    The Verdict

    At the time of writing Polymer is a mixed bag.
    The syntax is strange at first but you quickly get used to it and before you know it you’re writing Polymer code without even thinking about it.

    When everything is ideal writing Polymer apps is soooo good.

    With Polymer, getting into the mind frame of writing component based apps is incredibly easy and the codebase becomes a piece of cake to reason about, it just feels like the right way of building a web app.
    As for utilities and helper tools — polymer-cli and Polymer IDE, they’re not perfect… they’re pretty basic to be honest but they’re maturing and I wasn’t expecting much since I knew they weren’t all that powerful so there wasn’t exactly room for me to be disappointed.
    And now for the bad stuff, mainly the error logging…

    OH. MY. GOD.

    If the error logging wasn’t this terrible I’d tell you to use Polymer immediately but it is and for me wasting time deciphering WTF went wrong from a trace that’s like standing in front of an ocean and saying the error is in the wet part is just inexcusable!
    A question springs to mind here: if I’m having these kinds of problems on such a small and trivial project what would it be like to work on a real project?
    Trying to google solutions is useless since you’ll only get Polymer 1 answers. The documentation is ok but trying to find something specific is a pain in the ass.
    Personally I think the Polymer team is aware of these issues and they’re just building hype for when it’s ready.
    That’s the problem here, everything tied to Polymer feels like an unfinished product…
    The final verdict: Don’t use Polymer yet, it’s unfinished and other more mature frameworks will serve you better but keep an eye on it, it has a tonne of potential and when it’s finally ready you will seriously consider it for your next web app project!
    Share Article on:  or 
    Bojan Gvozderac profile image

    Bojan Gvozderac is an experienced web and mobile developer specializing in JavaScript with almost a decade and a half developing software Bojan has proven that he has the knowledge and the expertise to deliver the goods!
    If you'd like to get in touch and talk about potential projects, one of my articles, ask a question or just say "Hi!" please do by clicking  here.