Nikhil Raghavendra Nikhil Raghavendra - 22 days ago 9
JSON Question

Data binding in Polymer

I have this function which gives me a JSON return value when it is called.

getJSON function(url, success){
var ud = '_' + +new Date,
script = document.createElement('script'),
head = document.getElementsByTagName('head')[0]
|| document.documentElement;
window[ud] = function(data) {
head.removeChild(script);
success && success(data);
};
script.src = url.replace('callback=?', 'callback=' + ud);
head.appendChild(script);
}


And to call the function, I use the following code.

getJSON('https://newsapi.org/v1/articles?source=techcrunch&apiKey={APIKEY}', function(data){
//Stuff to be done with the data
});


And then I have a paper card to which I want to bind the JSON value that I get.

<paper-card heading="Card Title">
<div class="card-content">{{json}}</div>
</paper-card>


What I want to do is that call that declare the getJSON function the polymer way, call the function and set the JSON value returned to the
{{json}}
data element in the paper card. I have tried more than 5 ways of doing the above but I could not do what I wanted to. I am new to polymer so please help me.

Answer

Instead of writing your own getJSON() method, you could use Polymer's <iron-ajax> element to fetch the data for you.

The News API data looks similar to this JSON object:

{
  "status": "ok",
  "source": "the-next-web",
  "sortBy": "latest",
  "articles": [{
    "author": "TNW Deals",
    "title": "4 offers from TNW Deals you won’t want to miss",
    "description": "We’ve featured some great offers from TNW …",
  }, {
    "author": "Bryan Clark",
    "title": "Amazing 4k video of the Northern Lights",
    "description": "Tune in, and zone out …",
  }]
}

And I assume you want to display each article from the articles[] array.

The <iron-ajax> element could request the data from the News API and store the server response in lastResponse, which you could bind to a property that could be used in your template.

In the following example, where we see last-response="{{data}}", <iron-ajax> will output the News API response into data (i.e., like setting this.data = response, where response is the JSON object above). Given the shape of the data mentioned previously, we know that data.articles would access the array of articles, which could be passed to dom-repeat for iteration:

<template>
  <iron-ajax url="https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey=|APIKEY|" 
             auto
             last-response="{{data}}">
  </iron-ajax>

  <template is="dom-repeat" items="[[data.articles]]">
    <paper-card heading="[[item.title]]">
      <div class="card-content">
        <p>[[item.description]]</p>
      </div>
    </paper-card>
  </template>
</template>

Alternatively if you need to manipulate the response imperatively beforehand, you could setup an event listener for the <iron-ajax>.response event. The event detail contains the data in .response. You could process/modify that data, and assign results to this.articles, which is bound in the dom-repeat.

<template>
  <iron-ajax url="https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey=|APIKEY|" 
             auto
             on-response="_onResponse">
  </iron-ajax>

  <template is="dom-repeat" items="[[articles]]">
    <paper-card heading="[[item.title]]">
      <div class="card-content">
        <p>[[item.description]]</p>
      </div>
    </paper-card>
  </template>
</template>

<script>
  Polymer({
    ...
    _onResponse: function(e) {
      var data = e.detail.response;
      // do something with data...

      // set this.articles for dom-repeat
      this.articles = data;
    }
  });
</script>
Comments