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 Displaying the Photos

Antoine Boillot
Antoine Boillot
10,466 Points

Coded Dave's Flickr project in a different way : cannot understand what's wrong with my code.

Hey,

I'm currently going through the AJAX Basics course.

On stage 4, Dave creates a project that connects the Flickr API to retrieve photos of cats, dogs or mooses, depending on the button that is clicked by the user.

Here is below his code :

$(document).ready(function() {


 $('button').click(function () {
    // highlight the button
    // not AJAX, just cool looking
    $("button").removeClass("selected");
    $(this).addClass("selected");

    // the AJAX part
    var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
    var animal = $(this).text();
    var flickrOptions = {
      tags: animal,
      format: "json"
    };
    function displayPhotos(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>';
      $('#photos').html(photoHTML);
    }
    $.getJSON(flickerAPI, flickrOptions, displayPhotos);

  }); // end click

}); // end ready

The above works fine.

But, as I'm not a big fan of concatenation, I tried to get the same result by coding another way (to avoid concatenating anything).

Here is below my code:

$(document).ready(function() {
  $('button').click(function() {
    $('button').removeClass('selected');
    $(this).addClass("selected");
    var flickrAPI = 'http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?';
    var animal = $(this).text();
    var flickrOptions = {
      tags: animal,
      format: 'json'
    };
    var displayPhotos = function(data) {
      var $photosUl = $('<ul></ul>');
      $photosUl.appendTo('#photos');
      $.each(data.items, function(i, photo) {
        var $flickrPhotoItem = $('<li></li>');
        var $flickrPhotoLink = $('<a>');
        var $flickrPhotoThumbnail = $('<img>');
        $flickrPhotoItem.appendTo($photosUl).addClass('grid-25 tablet-grid-50');
        $flickrPhotoLink.appendTo($flickrPhotoItem).attr('href', photo.link).addClass('image');
        $flickrPhotoThumbnail.appendTo($flickrPhotoLink).attr('src', photo.media.m);          
      }); // end each
    }; // end displayPhotos
    $.getJSON(flickrAPI, flickrOptions, displayPhotos);
  }); // end click
}); // end ready

At first click, everything is working as expected.

The issue arises when trying to get photos of another animal: -> Photos are retrieved from the Flickr API, but instead of replacing the previous ones, it get displayed under them.

e.g. : -> 1st click = Cat => Cat photos are displayed -> 2nd click = Dog => Cat photos are STILL displayed above, followed by the newly retrieved dog ones. -> 3rd click = Moose => Cat photos displayed, followed by dogs ones, followed by mooses ones.

I don't understand such behaviour. What did I do wrong with my code ?

Thanks a lot for your help.

Cheers,

Antoine

2 Answers

Antoine Boillot
Antoine Boillot
10,466 Points

Hey,

Found the issue :

When inserting the <ul></ul> tags in the #photos div, I used an appendTo() method, which as it indicates, append some element to another, BUT without replacing some existing ones that might already be there.

I should have used the html() method, that actually replace the content of the matched element.

Here is below the corrected (and working) code:

$(document).ready(function() {
  $('button').click(function() {
    $('button').removeClass('selected');
    $(this).addClass('selected');
    var flickrAPI = 'http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?';
    var animal = $(this).text();
    var flickrOptions = {
      tags: animal,
      format: 'json'
    };
    var displayPhotos = function(data) {
      var $photosUl = $('<ul></ul>');
      $('#photos').html($photosUl);
      $.each(data.items, function(i, photo) {
        var $flickrPhotoItem = $('<li></li>');
        var $flickrPhotoLink = $('<a>');
        var $flickrPhotoThumbnail = $('<img>');
        $flickrPhotoItem.appendTo($photosUl).addClass('grid-25 tablet-grid-50');
        $flickrPhotoLink.appendTo($flickrPhotoItem).attr('href', photo.link).addClass('image');
        $flickrPhotoThumbnail.appendTo($flickrPhotoLink).attr('src', photo.media.m);        
      }); // end each
    }; // end displayPhotos
    $.getJSON(flickrAPI, flickrOptions, displayPhotos);
  }); // end click
}); // end ready

Cheers,

Antoine

Andrew Dunn
Andrew Dunn
14,718 Points

Bah beat me to it - I thought that line looked funny without the .html() method.

Kudos on solving your own dilemma!

Antoine Boillot
Antoine Boillot
10,466 Points

:) Thanks! And thanks for looking at it!

Atanas Sqnkov
Atanas Sqnkov
14,981 Points

Here, get some more Kudos!