Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript AJAX Basics (retiring) AJAX and APIs Stage 4 Challenge

Paul Yorde
Paul Yorde
10,497 Points

Is it possible to set the number of flickr results?

I am getting 20 images from the flickr public API. I found that I can set perpage parameter with an api key, but I haven't seen that parameter for the public key. Is this possible?

3 Answers

I don't believe it is available as a parameter, but I did figure out a method for you to use. I am pretty damn proud of it, I must say. You can customize this to how you would like it and add blocks of 20 to the results. You'll see on these pages that I've added in 20, 40, 60, 80, 100, and 200 images per page, and you can add as many as you like, although I would say within reason. 200 should probably be the max, so that you don't bog down the Flickr servers with too many requests.

Also, you are likely to see some pictures repeat, because there are a limited number of pictures that are public on Flickr.

Here are all of the files. I have written plenty of comments in the app.js file so that you can tell what's going on:

/* Just add the following to the VERY BOTTOM of main.css */
.resultsSelector {
  text-decoration: underline;
}

.resultsSelected {
  text-decoration: none;
}
<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>AJAX Flickr Photo Search</title>
  <link href='http://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
  <link rel="stylesheet" href="css/main.css">
  <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
  <script src="js/app.js"></script>
</head>
<body>
  <div class="grid-container centered">
    <div class="grid-100">
      <div class="contained">
        <div class="grid-100">
          <div class="heading">
            <h1>Flickr Photo Search</h1>
            <form id="flickrSearchForm">
              <label for="search">Type a search term</label>
              <input type="search" name="search" id="search">
              <input type="submit" value="Search" id="submit">
              <!-- Note that the currently selected number of results has an extra class of resultsSelected -->
              <!-- To add more options to results, just make a new link with a blank href and give it a class of resultsSelector with the number of requests as the link text i.e. for 120 images, <a href="" class="resultsSelector">120</a> -->
              &nbsp;&nbsp;&nbsp;<span style="font-size: 1.5em;">Results per page: &nbsp;<a href="" class="resultsSelector resultsSelected">20</a> <a href="" class="resultsSelector">40</a> <a href="" class="resultsSelector">60</a> <a href="" class="resultsSelector">80</a> <a href="" class="resultsSelector">100</a> <a href="" class="resultsSelector">200</a></span> 
            </form>
          </div> 
        </div>

        <ul id="photos">

        </ul>
      </div>
    </div>
  </div>
</body>
</html>
/* app.js

NOTE: See main.css at the very bottom of that page for the two simple classes I added. 

*/

//Add numJSONRequests to global scope so that the search bar can fire off right away with the selected results of 20 images
var numJSONRequests = 1;

$(document).ready(function() {
  $(".resultsSelector").click(function (evt) {
    //Prevent default action
    evt.preventDefault();

    //Set text decoration of current selected to underline
    $(".resultsSelected").css('text-decoration', 'underline');
    //Remove class from current selected
    $(".resultsSelected").removeClass("resultsSelected");
    //Set text decoration of new selected to none
    $(this).css('text-decoration', 'none');
    //Add class to new selected
    $(this).addClass("resultsSelected");


    /* 
      The reason why I divided by 20 on the end of the statement down below is because the public API key sends back 20 images per
      public request. And in order to get back more than 20 pictures, we have to make more than one request, which is why we iterate
      through a for loop as you'll see below.  Now, you can only do blocks of 20 since you can't set parameters in the public API to
      limit/exceed the number of pics the API sends you. This is why each link has to be a multiple of 20.
    */

    //Set the number of JSON requests to be the selected number of pics you wish to see on a page
    numJSONRequests = parseInt($(".resultsSelected").text(), 10) / 20;
  });


 $('#flickrSearchForm').submit(function (evt) {
   //Prevent form from loading a new page
   evt.preventDefault();

   //Clear current photos (if any)
   $("#photos").html("");

   //Iterate through a for loop so that we can send out multiple JSON requests
   //Each loop sends back 20 images, so if numJSONRequests is 1, then for loop executes only once
   //Sending back 20 images, and so on.

   //You cannot use variables in place of the url, data, and callback parameters of getJSON for multiple requests
   //unless those variables are differently named.  Since I couldn't use arrays for those parameters either, it's much
   //easier to just use the actual data instead of a variable.
   for (i = 0; i < numJSONRequests; i += 1){
    $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?", 
      {
        tags: $("#search").val(),
        format: "json"
      }, function (data) {
        var photoHTML = '<ul>';
      $.each(data.items,function(i,photo) {
        photoHTML += '<li class="grid-25 tablet-grid-50">';
        photoHTML += '<a href="' + photo.link + '" class="image">';
        photoHTML += '<img src="' + photo.media.m + '"></a></li>';
      }); // end each
        photoHTML += '</ul>';

        //Changed html to append so that each iteration will append to the #photos div
        $('#photos').append(photoHTML);
      }); //end getJSON
    } //end for method
  }); //end submit
}); //end ready
nico dev
nico dev
20,364 Points

Wow! That meant some learning on this end.

Thank you!

Dylan Macnab
Dylan Macnab
24,861 Points

I don't think this parameter is available to flickr's public API. I can't find where I read that, but I remember trying to do a similar thing when taking that course.

Christopher Parke
Christopher Parke
21,978 Points

I just seem to get the same page loading over and over when I put the request in a for loop like above. I doubt there's only 16 public photos available at any given time. I'm just not sure what's stopping the first request from returning more unique results...