Taking custom Polymer element <x-flickr> to the next level
Older Article
This article was published 12 years ago. Some information may be outdated or no longer applicable.
I wanted to extend the features of my first custom Polymer element, <x-flickr>. The Polymer engineers provide great support on both Twitter and StackOverflow, so I felt confident they’d answer my questions. In the previous article I mentioned using Flickr’s REST API to search for photos with a given tag. The result set returns enough information to build up the src attribute for the img tag. But to dig deeper and pull further information about the image (the author, the description of the photo), another API call needs to happen.
Two ways to tackle this: via scripting, and via Polymer elements (the Polymeric way). Let’s walk through both.
The polymeric way
Instead of making a JSONP call to the Flickr API, we can fire a simple AJAX call, constructed like this:
<polymer-ajax
auto
handleAs="json"
response="{{data}}"
url="http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key={{apikey}}&tags={{tag}}&per_page={{amount}}&page=1&format=json&nojsoncallback=1"
></polymer-ajax>
After this, we create the template just as before, and inside the repeater (repeat={{photo in photos}}) we can make yet another AJAX call to grab the details of a given photo:
<polymer-ajax
auto
handleAs="json"
response="{{photo.info}}"
url="http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key={{apikey}}&photo_id={{photo.id}}&format=json&nojsoncallback=1"
></polymer-ajax>
We also need to update the Element specification inside the <script> tag:
Polymer('x-flickr', {
apikey: '',
amount: 10,
data: null,
dataChanged: function () {
this.photos = this.data.photos.photo;
this.fire('x-flickr-load', { response: this.photos });
},
});
This approach also shifts the dependencies in bower.json significantly. The only package you need is ‘polymer-ajax’.
I’ve made these changes and created a branch on GitHub so you can see how it all comes together.
The scripted way
You can also achieve the above functionality using scripts. Here, we’ll extend the <script> part of the template and use the length property of the photos array.
First, instead of building up the src attribute, we create an src key:
photo.src =
'http://farm' +
photo.farm +
'.staticflickr.com/' +
photo.server +
'/' +
photo.id +
'_' +
photo.secret +
'.jpg';
Then access it inside the template:
<img src="{{photo.src}}" class="img-thumbnail" />
We can also store the ID of the photo in a similar fashion and construct a call to grab the description or any other detail:
fetchAuthor: function(photo) {
var jsonp = document.createElement('polymer-jsonp');
jsonp.url = 'https://api.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key=' + this.apikey + '&photo_id=' + photo.id + '&format=json&jsoncallback=';
jsonp.addEventListener('polymer-response', function(e) {
photo.author = this.response.photo.owner.realname;
});
jsonp.go();
}
I’ve created another branch on GitHub for the scripted approach. Have a look.
This shows the flexibility of Polymer and the multiple ways of achieving the same functionality. According to the Polymer engineers, the right way is the declarative way (first option).