25

I have an Angular 1.x app, which I am trying to update to material design with the help of Polymer 1.0. I must state that I am only using the paper elements as normal building blocks and that I am not writing any custom Polymer code.

So far, I have encountered 2 problems, both dealing with nested Polymer elements, so I guess the solution will be the same or at least very similar.


Problem 1

Using ng-repeat on a paper-item.

HTML code (with Angular templating syntax)

<paper-item data-ng-repeat="event in events">
    <paper-item-body two-line>
        <div>{{event.title}}</div>
        <div secondary>{{event.description}}</div>
    </paper-item-body>
</paper-item>

The following code does not run as it produces the following error:

TypeError: Cannot read property 'childNodes' of undefined
    at g (angular.js:7531)
    at g (angular.js:7531)
    at N (angular.js:8127)
    at g (angular.js:7527)
    at angular.js:7402
    at $get.h (angular.js:7546)
    at m (angular.js:8159)
    at angular.js:27052
    at Object.fn (angular.js:15474)
    at m.$get.m.$digest (angular.js:15609)

However, if I use the following code, the code does run without error:

<div data-ng-repeat="event in events">
    <paper-item-body two-line>
        <div>{{event.title}}</div>
        <div secondary>{{event.description}}</div>
    </paper-item-body>
</div>

Notice that I only changed the root element (from paper-item to div).


Problem 2

Trying to use google-map to show a marker on a map. The map centers, but there is no marker.

HTML code (with Angular templating syntax)

<google-map latitude="{{event.y_wgs}}" longitude="{{event.x_wgs}}">
    <google-map-marker latitude="{{event.y_wgs}}" longitude="{{event.x_wgs}}"></google-map-marker>
</google-map>

HTML output (as compiled by Angular at runtime):

<google-map latitude="12.345" longitude="12.345">
    <google-map-marker latitude="NaN" longitude="NaN"></google-map-marker>
</google-map>

Notice the inner tag google-map-marker has NaN as latitude and longitude, while the outer google-map works as intended. This explains why the map centers OK, but no marker is present.


TL;DR

Nesting Polymer elements and using Angular double-mustache syntax is probably causing the conflict, as the inner Polymer elements treat it as Polymer code and not Angular code.

Any ideas how to resolve this problem?

alesc
  • 2,776
  • 3
  • 27
  • 45
  • 1
    Your first problem is likely related to the ShadyDOM shim. When you compose things into Polymer element imperatively, you have to use the `Polymer.dom` API to satisfy ShadyDOM (which Angular does not). Try running your example on Chrome, but set `window.Polymer.dom = true` before importing Polymer to see if it works under native Shadow DOM. Also, Polymer will only act on `{{ }}` syntax in the context of a template it's processing. – Scott Miles Jun 14 '15 at 10:40
  • Thank you for your comment. I am using Chrome, but when I set `window.Polymer.dom = true` in various locations, nothing happens. Except if I put it after including Polymer elements, then I get multiple error with the following content: `Polymer.dom is not a function`. – alesc Jun 14 '15 at 10:49
  • Don't put `window.Polymer.dom = true` in _various places_ :), only set that before importing Polymer. If it doesn't have any effect, then I don't know what the problem is. – Scott Miles Jun 14 '15 at 11:02
  • I was putting it in various locations because it didn't work. I have tried the following: (1) putting it before anything and got `Cannot set property 'dom' of undefined`; (2) after `webcomponents.js` but before `polymer.html` and got no such error, but it still doesn't work (got the error from the original post); (3) after both `webcomponents.js` and `polymer.html` and got the error from my previous comment `Polymer.dom is not a function`. Overall, it doesn't seem to change anything. – alesc Jun 14 '15 at 11:16
  • Other than ngMaterial being in early stages (I suspect they're getting close to 1.0), is there any reason not to use it, instead of Polymer? I don't think the Angular and Polymer were designed to be used together. – Devin H. Jun 16 '15 at 15:12
  • Yes, Angular and Polymer are very similar, but that does not mean they are not ment to be used together. For example, a Polymer developer made this video on the aforementioned topic: [Youtube](https://www.youtube.com/watch?v=p1NpZ-0Op0w). – alesc Jun 17 '15 at 06:33
  • 2
    See https://www.polymer-project.org/1.0/docs/devguide/settings.html It should be: `window.Polymer = window.Polymer || {}; window.Polymer.dom = 'shadow';` – Justin Fagnani Jun 19 '15 at 00:04
  • @JustinFagnani thanks! This solved problem #1. Any ideas why this doesn't work on problem #2. Since there is a bounty on the question, you should make an answer from your comment. – alesc Jun 19 '15 at 07:45
  • @alesc My point is, if you can do it in Angular, why not? Why include an entirely different framework? (sorry if the video covers this, don't have access to sound atm) – Devin H. Jun 19 '15 at 17:46

2 Answers2

3

If your aim is to use Material Design (which for web based apps boils down to using the correct themes), I just saw Angular Material (https://material.angularjs.org/latest/#/). Maybe that would help?

Neeraj
  • 8,408
  • 8
  • 41
  • 69
  • I am currently usin this, but this is old Polymer and I want to migrate to pure Polymer 1.0 as the angular-material lags behind the main development branch of Polymer. – alesc Jun 19 '15 at 17:49
0

The first problem can be solved by using

window.Polymer = {dom: 'shadow'};

as stated by Justin Fagnani in the comments, with slightly different syntax than stated in the polymer docs, otherwise it will not be recognized in Firefox/IE, see https://github.com/Polymer/polymer/issues/1844

However, I guess that means that you won't get any performance improvements that were introduced with shady DOM.

Kristjan Liiva
  • 9,069
  • 3
  • 25
  • 26