Search code examples
polymerweb-component

Polymer 1.0 services issue


I'm working on a reddit client using polymer to check out web compoments technologies. I started with the 0.5 version and got back on this project recently. That when I found out that polymer had the 1.0 released so I started over (as it wasn't that advanced anyway).

I have a service that use the iron-ajax to request reddit api and look for the posts. Here is the code :

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">

<dom-module id="reddit-list-service">
    <template>
        <iron-ajax
            url='https://www.reddit.com/new.json'
            handle-as='json'
            debounce-duration="300"
            on-response='handleResponse'
            debounce-duration="300"
            auto>

        </iron-ajax>
    </template>
</dom-module>

<script>
    (function () {
        Polymer({
            is: 'reddit-list-service',
            properties: {
                modhash: {
                    type: String,
                    value: function() {
                        return '';
                    }
                },
                posts: {
                    type: Array,
                    value: function () {
                        return [];
                    }
                },
                after: {
                    type: String,
                    value: function () {
                        return '';
                    }
                }
            },

            // Update object properties from the ajax call response
            handleResponse: function (resp) {
                this.properties.modash = resp.detail.response.data.modhash;
                this.properties.posts = resp.detail.response.data.children;
                this.properties.after = resp.detail.response.data.after;
                this.post = this.properties.posts; // just to try
                console.log(this.properties.posts);
            }
        });
    })();
</script>

My log shows me that I get posts from the API and that's great!

Here's the issue when I want to use this service to make a list out of the posts array I can't figure out how to get them into my list compoment which is below :

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../reddit-list-service/reddit-list-service.html">

<dom-module id="reddit-post-list">
    <template>
        <reddit-list-service posts="{{posts}}">
        </reddit-list-service>

        <template is="dom-repeat" id="post-list" posts="{{posts}}">
            <p>{{post.author}}</p>
        <template>
    </template>
</dom-module>

<script>
    (function () {
        Polymer({
            is: 'reddit-post-list',
            properties: {
            },
        });
    })();
</script>

I've tried several think I saw in the documentation but I can't figure out what's wrong the author property doesn't show up.

Any clue?


Solution

  • You have a few things that aren't quite right here. In reddit-post-list you are not using the dom-repeat template correctly. See below:

    <link rel="import" href="bower_components/polymer/polymer.html">
    <link rel="import" href="reddit-list-service.html">
    
    <dom-module id="reddit-post-list">
        <template>
            <reddit-list-service posts="{{posts}}"></reddit-list-service>
            <template is="dom-repeat" items="[[posts]]">
                 <p>{{item.data.author}}</p>
            </template>
        </template>
    </dom-module>
    
    <script>
        Polymer({
            is: "reddit-post-list"
        });
    </script>
    

    You need an attribute called items which is the array the dom-repeat will iterate over. Inside the iteration you need to refer to item as this is the array item for the current iteration. Here are the docs.

    For you reddit-list-service, you need to set the the reflectToAttribute and notify attributes to true on your posts property. This means that any changes to this property are reflected back on the posts attribute on the reddit-list-service element. See here for more information.

    <link rel="import" href="bower_components/polymer/polymer.html">
    <link rel="import" href="bower_components/iron-ajax/iron-ajax.html">
    
    <dom-module id="reddit-list-service">
        <template>
            <iron-ajax auto url="https://www.reddit.com/new.json" handle-as="json" on-response="handleResponse"></iron-ajax>
        </template>
    </dom-module>
    
    <script>
        Polymer({
            is: "reddit-list-service",
            properties: {
                modhash: {
                    type: String,
                    value: ""
                },
                posts: {
                    type: Array,
                    value: function () {
                        return [];
                    },
                    reflectToAttribute: true, // note these two new attributes
                    notify: true
                },
                after: {
                    type: String,
                    value: ""
                }
            },
    
            // Update object properties from the ajax call response
            handleResponse: function (resp) {
                this.modash = resp.detail.response.data.modhash;
                this.posts = resp.detail.response.data.children;
                this.after = resp.detail.response.data.after;
            }
        });
    </script>
    

    I have also tidied up the following things:

    • Removed the immediately called function wrapper from the <script> tags as these are not needed.
    • When referring to properties in your element you only need to use this.PROPERTYNAME rather than this.properties.PROPERTYNAME.
    • Having looked at the JSON returned, it appears that the author property is on the another property called data.
    • When you declare a value for a property in your element, you only need to have a function that returns a value if the property type is an Object or Array.