0

I'm getting data through JSON

$.getJSON('http://api.flickr.com/services/rest/'
            + '?format=json&method=flickr.photosets.getPhotos'
            + '&photoset_id=' + photoset_id + '&per_page=1000' 
            + '&page=1' + '&api_key=' + apiKey 
            + '&user_id=' + userId + '&jsoncallback=?', 
    function (data) {
        var fullPhotoURL, flickrLink;
        var images = [];
        var basePhotoURL;
        var fullPhotoURL;

        $.each(data.photoset.photo, function (i, flickrPhoto) {
            var basePhotoURL = 'http://farm' + flickrPhoto.farm 
                 + '.static.flickr.com/' + flickrPhoto.server + '/' 
                 + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";

            var fullPhotoURL = 'http://farm' + flickrPhoto.farm 
                + '.static.flickr.com/' + flickrPhoto.server + '/' 
                + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";

            images.push($("<img/>").attr("src", basePhotoURL));
        });

        $.each(images, function (index, img) {
            img.appendTo("#photographs").wrap(("<div class='item'></div>"));

        });

    });

I want to append two a's (with href basePhotoURL & fullPhotoURL) to each .item div.

$(".item")
    .append("<a href='" + basePhotoURL + "'.jpg' class='zoom' />");
$(".item")
    .append("<a href='" + fullPhotoURL + "' class='flickr' target='_blank' />");

Problem is, when i put those in the second each function, those two a's get appended for every .item that is present in #photographs (divception :-)) (so, 300 items x 2 a's PER .item). When i put those two a's outside the last each function, i get an undefined error. by the way, don't mind the fullPhotoURL and basePhotoURL variables' values; they are not correct.

Thanks!

10
  • why do you need two loops there? Commented Jan 18, 2013 at 20:41
  • This was proposed from another stackoverflow thread actually. Commented Jan 18, 2013 at 20:44
  • I'm trying to understand the motivation for the second loop too. Could you provide a link to that thread? Commented Jan 18, 2013 at 20:46
  • The second loop is so that you only do one paint/append to the DOM, instead of every loop around adding it again and again. Commented Jan 18, 2013 at 20:48
  • 2 loops don't help at all, you have the same amount of insertions. Only solution would be a surrounding div, then it would be just 1 append. Commented Jan 18, 2013 at 20:51

4 Answers 4

1

A combination of Eli's answer, and this post. Here you'll append the data to the DOM only once.

.getJSON('http://api.flickr.com/services/rest/?format=json&method=flickr.photosets.getPhotos&photoset_id=' + photoset_id + '&per_page=1000' + '&page=1' + '&api_key=' + apiKey + '&user_id=' + userId + '&jsoncallback=?', function(data) {

    var dataToAppend = ''
    $.each(data.photoset.photo, function(i, flickrPhoto){
        var basePhotoURL = 'http://farm' + flickrPhoto.farm + '.static.flickr.com/'
        + flickrPhoto.server + '/' + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";  

        var fullPhotoURL = 'http://farm' + flickrPhoto.farm + '.static.flickr.com/'
        + flickrPhoto.server + '/' + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";          

        var $img = $("<img/>").attr("src", basePhotoURL);
        var $wrap = $("<div class='item'></div>");
        $wrap.append($img);
        $wrap.append("<a href='" + basePhotoURL + "'.jpg' class='zoom' />");
        $wrap.append("<a href='" + fullPhotoURL + "' class='flickr' target='_blank' />");
        dataToAppend += $wrap;
    });
    $'#photographs').append(dataToAppend);
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. It all looks logical when it's there, but i when i have to figure it out myself.. :-)
1

Why not just append them directly to the div tag?

    var div = $("<div class='item'></div>");
    div.append(....);
    div.append(....);

Also, you cant access the variables from the first loop in your second loop. If you really need 2 loops for some reason you can pass them along in the array.

    images.push({base: basePhotoURL, full: fullPhotoURL});

and create the img in the second loop (or pass it along with the rest).

If you are concerned about performance, do:

    var plist = $("<div></div>");
    $.each(data.photoset.photo, function (i, flickrPhoto) {
        var row = $("<div class='item'></div>");

         //add stuff

        plist.append(row);
    });
    plist.appendTo("#photographs");

1 Comment

Thanks (see other answers for info)
1

I was able to get the format your looking for using this as well, basically the same thing.

$.getJSON('http://api.flickr.com/services/rest/?format=json&method=flickr.photosets.getPhotos&photoset_id=' + photoset_id + '&per_page=1000' + '&page=1' + '&api_key=' + apiKey + '&user_id=' + userId + '&jsoncallback=?', function (data) {
    var fullPhotoURL, flickrLink;
    var images = [];
    var basePhotoURL;
    var fullPhotoURL;

    $.each(data.photoset.photo, function (i, flickrPhoto) {
        var basePhotoURL = 'http://farm' + flickrPhoto.farm + '.static.flickr.com/' + flickrPhoto.server + '/' + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";
        var fullPhotoURL = 'http://farm' + flickrPhoto.farm + '.static.flickr.com/' + flickrPhoto.server + '/' + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";

        $('<img/>', { 'src': basePhotoURL }).appendTo("#photographs").wrap('<div/>', { 'class': 'item' }).append('<a href="' + basePhotoURL + '.jpg" class="zoom" /> <a href="' + fullPhotoURL + '" class="flickr" target="_blank" />');
    });
});

Comments

0

I think you're making things harder than they have to be. Here's my proposed changes.

.getJSON('http://api.flickr.com/services/rest/?format=json&method=flickr.photosets.getPhotos&photoset_id=' + photoset_id + '&per_page=1000' + '&page=1' + '&api_key=' + apiKey + '&user_id=' + userId + '&jsoncallback=?', function(data) {

    $.each(data.photoset.photo, function(i, flickrPhoto){
        var basePhotoURL = 'http://farm' + flickrPhoto.farm + '.static.flickr.com/'
        + flickrPhoto.server + '/' + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";  

        var fullPhotoURL = 'http://farm' + flickrPhoto.farm + '.static.flickr.com/'
        + flickrPhoto.server + '/' + flickrPhoto.id + '_' + flickrPhoto.secret + "_b.jpg";          

        var $img = $("<img/>").attr("src", basePhotoURL);
        var $wrap = $("<div class='item'></div>");
        $wrap.append($img);
        $wrap.append("<a href='" + basePhotoURL + "'.jpg' class='zoom' />");
        $wrap.append("<a href='" + fullPhotoURL + "' class='flickr' target='_blank' />");

        $wrap.appendTo('#photographs')

    });

});

So now we're generating the img, then its wrapper, then appending the img to the wrapper, then appending the anchors to the wrapper, then appending the wrapper to the photographs div. And we're doing it all within one loop, all at once. No need for a second loop, and thus no need for an image array.

1 Comment

Excellent. As i've typed in the other answer; thanks for the help; i'm still new at this and i'm learning fast! I can't test right now; but i'm guessing this is correct and will help me in the future!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.