Flickr uses JSONP to deliver its JavaScript APIs. jQuery handles JSONP automatically with its $.getJSON()
method but in JavaScript the approach we should follow it’s a little bit more complicated.
JSONP needs a callback function to be executed when retrieving data in the form http://api/json?callback=?
. The last question mark in our hypothetical URI must be replaced by the name of our function.
This function must be globally accessible. In other words, it must appear in the global scope. Here’s an example:
function log( data ) {
console.log( data );
}
document.addEventListener( "DOMContentLoaded", function() {
var script = document.createElement( "script" );
script.src = "http://api/json?callback=log";
document.body.appendChild( script );
});
When our code it’s executed, the log()
function will output Object
to the console if there are no errors. As you can see, the remote feed has been included in our document with a script
element. This is the only way to avoid problems with the same domain policy when the remote server doesn’t have a Access-Control-Allow-Origin
header set.
Since in JavaScript the global scope is represented by the window
object, we can simply attach our code in a method that will become a property of the global object.
(function() {
function Flickr() {
this.init();
}
Flickr.prototype = {
init: function() {
this.user = "123194585@N06"; // Flickr user ID
this.album = "72157646849974903"; // Album/set's ID
window.getPhotos = this.getPhotos; // Our method as a property of window, i.e. global
this.getJSON();
},
getJSON: function() {
// Complete API URL, with parameters
var src = "http://api.flickr.com/services/feeds/photoset.gne?nsid=" + this.user + "&set=" + this.album + "&format=json&jsoncallback=getPhotos";
var script = document.createElement( "script" );
script.src = src;
document.body.appendChild( script );
},
getPhotos: function( data ) {
// data is the JSON object returned by Flickr
var limit = 3;
if( data && data.items ) {
var title = data.title;
var items = data.items;
var albumTitle = title.replace( "Content from ", "" );
var html = "<h3>" + albumTitle + "</h3>";
html += "<div class='images'>";
for( var i = 0; i < items.length; ++i ) {
var item = items[i];
var n = i + 1;
if( n <= limit ) {
html += "<a href='" + item.link + "'><img src='" + item.media.m + "' alt='' /></a>";
}
}
html += "</div>";
document.querySelector( "#flickr" ).innerHTML = html;
}
}
};
document.addEventListener( "DOMContentLoaded", function() {
var flickrFeed = new Flickr();
});
})();