Thursday, January 23, 2014

Using Polymer Tags in an AngularJS Application (with Routing)


The question I would like to answer today is how to go about getting a Polymer working inside of an AngularJS application. I already know how to do this in the Dart version of both libraries, so hopefully this will prove to be an easy answer.

They are never easy answers.

After last night, I have an <x-pizza> Polymer that builds pizzas:



Let's see if I can use that Polymer in an Angular pizza shop application. As with the Dart version, I will try to get this working with a simple, routing-only Angular application. In my mind at least, including the routing ensures that I am exercising a decent amount of the library. That goes against my usual approach of limiting the number of moving parts, but without some interesting bits of the library in place, I feel as though it is too easy to think I have it legitimately incorporated.

I start with a Bower install of Angular: bower install angular --save. I could have used Angular from the CDN, but I am already using Bower for Polymer so I stay consistent. For the routing, I also need to bower install angular-route --save.

That leaves me with a bower.json with the following dependencies:
{
  "name": "angular_example",
  // ...
  "dependencies": {
    "angular": "~1.2.9",
    "polymer": "~0.1.3",
    "angular-route": "~1.2.9"
  }
}
One thing that the JavaScript world makes easier than the Dart equivalent is the ability to run any number of scripts and libraries at the same time. There is a cost to doing so, of course, but in this case it helps.

In my main page, I include everything. I include the Polymer library. I include the Polymer definition from last night. I include Angular and the Angular routing library. I include the Angular application. And I point the page to the Angular application and include an ng-view tag to hold the application:
<!doctype html>
<html ng-app="pizzaStoreApp">
  <head>
    <title>Pizza!</title>
    <script src="bower_components/platform/platform.js"></script>
    <link rel="import" href="elements/x-pizza.html">
    <script src="bower_components/angular/angular.min.js"></script>
    <script src="bower_components/angular-route/angular-route.min.js"></script>
    <script src="scripts/pizza_store.js"></script>
  </head>
  <body>
    <div class="container">
      <h1>JavaScript Pizza Shoppe</h1>
      <div ng-view></div>
    </div>
  </body>
</html>
The ng-app attribute on the <html> tag ties this page to an Angular application named pizzaStoreApp. I define that in scripts/pizza_store.js as a simple router-only Angular application:
'ngRoute'
]);

pizzaStoreApp.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/home', {
        templateUrl: 'scripts/partials/home.html'
      }).
      when('/pizza/custom', {
        templateUrl: 'scripts/partials/custom.html'
      }).
      otherwise({
        redirectTo: '/home'
      });
  }
]);
The two partials are simple HTML samples. I use last night's SVG-based Polymer in the custom.html partial:
<h3>Oooh! Let's make beautiful pizza together</h3>
<p>
  <x-pizza></x-pizza>
</p>
And that turns out to be all that is needed:



That was pleasantly easy. Much of that was made easier for having already done it in Dart, but I do think the JavaScript version of Angular remains slightly more polished than its Dart cousin. Regardless, I now have Angular and Polymer playing nicely together in both JavaScript and Dart.


Day #1,005

1 comment: