Taking custom Polymer element <x-flickr> to the next level

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 was very confident that they'd answer my questions. In the previous article I have mentioned that I am using Flickr's REST API to search for photos with a given tag. The resulset returns enough information to build up the src attribute for the img tag. However, to dig deeper into the depths and get further information about the image - such as the author or the description of the photo - another API call needs to be made.

There are two ways to approach this problem - via scripting and simply via using polymer elements aka the Polymeric way. Let's discuss these now.

The polymeric way
As opposed to making a JSONP call to the Flickr API, we can make a simple AJAX call, constructed in the following way:

<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 can create the template just as before, and inside the repeater (repeat={{photo in photos}}) we can make yet another AJAX call, this time to get 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>

And 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});
            }
        });

Using this solution also means that the dependencies in bower.json change significantly - the only package that we require is 'polymer-ajax'.

I have made these changes and created a branch on GitHub so you guys can check out how this all comes together.

The scripted way

It's also possible to achieve the above functionality using scripts. In this way, we will be extending the <script> part of the template and we'll also utilise the length property of the photos array.

First of all - instead of building up the src attribute we can create an src key:

photo.src = 'http://farm' + photo.farm + '.staticflickr.com/' + photo.server + '/' + photo.id + '_' + photo.secret + '.jpg';

And later on access this 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 get 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();
}

For your convenience I have created another branch on GitHub for this way of creating the element as well. Check it out.

This shows the great flexibility of Polymer and the numerous ways of achieveing the same functionality. According to the Polymer engineers the right way is the declarative way (first option).

Show Comments