Question

Say I have an index.html that contains a JSON wad inside the body:

<!doctype html>
...
    <head>
        ...
        <!-- build:css styles/main.css -->        
        <link rel="stylesheet" href="styles/main.css">
        <!-- endbuild-->

        <!-- Place your HTML imports here -->
        <script src="bower_components/platform/platform.js"></script>
        <link rel="import" href="elements/video-group.html">
    </head>
    <body>

        <script>

            videos:[
                 {
                    "name": "Mike Waters",
                    "id": "Fp1wPwszF9M"
                 },
                 {
                    "name": "Tom Valone",
                    "id": "H-l2cq-MXUs"
                 },
                 {
                    "name": "Wide Awake",
                    "id": "k0BWlvnBmIE"
                 },
                 {
                    "name": "Roar",
                    "id": "CevxZvSJLk8"
                 }
             ]

        </script>

        <!-- Slick Video Carousel -->
        <video-group data="{{videos}}"></video-group>

        <script>
        document.addEventListener('WebComponentsReady', function() {
            // Perform some behaviour

        });
        </script>

    </body>
</html>

How can I use that JSON wad inside my video-group element to produce a video carousel? I tried publishing a "data" attribute on my video-group element and passing it in via double mustache braces for illustrating what I am attempting, but it doesn't work.

I guess a broader question can be asked: can only strings be passed into custom element attributes?

UPDATE: @ebidel helped me out once again, so here's the working example, passing in the data in directly on the attribute:

<video-group data='[{"name": "Mike Waters","id": "Fp1wPwszF9M"},{"name": "Tom Valone","id": "H-l2cq-MXUs"},{"name": "Wide Awake","id": "k0BWlvnBmIE"},{"name": "Roar","id": "CevxZvSJLk8"}]'></video-group>

And in my video-group element I updated the ready function to evaluate that expression being passed in so that I can actually use the data:

ready: function(){                                
    this.data = eval(this.data) || []; 
},
dataChanged: function() {

    // Create the Carousel
    this.slick(this.data);
},
...
// Creates a Slick Carousel
slick: function(data) {

    // Slick it up!
    $('#carousel').slick({
        arrows: true,
        centerPadding: '50',
        dots: true,
        infinite: 'true'
    });

    // Add Slides
    data.forEach(function(element, index, array){            

        // Create a template for each slide
        var slideTemplate = $('<div><iframe width="420" height="315" src="//www.youtube.com/embed/' + array[index].id + '" frameborder="0" allowfullscreen></iframe></div>');

        // Append Each Slide to the Carousel
        $('#carousel').slickAdd(slideTemplate);

    });

Here's one thing that tripped me up at first, and I'm not sure if its a Polymer thing or not, but I had to update my div#carousel in my template to look like this:

<div id="carousel" />

Before I had just a standard /div closing tag and it was for some reason adding an empty child div that way, but as soon as I added the self-closing tag it went away. Weird right? or is this expected Polymer template behavior?

Was it helpful?

Solution

Polymer elements have the ability to take object/arrays as attributes if you properly hint the type of the published property. For example:

<roster-list persons='[{"name": "John"}, {"name": "Bob"}]'></roster-list>

More info here: http://www.polymer-project.org/docs/start/usingelements.html#objectarray

The other thing you can do is just set the property at runtime:

<video-group id="videog"></video-group>
<script>
  var videos = [...];
  document.addEventListener('polymer-ready', function() {
    document.querySelector('#videog').data = videos;
  });
</script>

Note: I'm using the polymer-ready event here. WebComponentsReady is only for vanilla custom elements.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top