1

I have a list of previewed posts on my page. When they're clicked on, they should load the full text of the post, load the comments, and slide down to reveal both.

I have one function, partialSlide, that simulates slideDown, but starting at a specified height - it's adapted from this answer. The other two functions, loadFullPost and loadComments are mine.

All the events are firing, but partialSlide is firing before loadComments is finished, so it's not taking them into account when calculating the height, and hence they're being cut off.

Why is that happening when I have them set up in a when > then format?

$.when(loadComments(divID,postID)).done(partialSlide(divID));

Am I misunderstanding how promises work in jQuery? Elsewhere in my code they've worked as expected (the then only runs once the when is done).

Full functions below:

function loadFullPost(permalink,divID,postID) {
    $.when($.when($.ajax({url: permalink+"?ajax=true", success:                 
       function(result){$("#"+divID+"").html(result);}})).then
           (function( data, textStatus, jqXHR ) {
            $.when(loadComments(divID,postID)).done(partialSlide(divID));
    }));    
}

function loadComments(divID,postID) {
    $.ajax({url: "ajax-comments/?post_id=" + postID, success:      
    function(result){
        $("#" + divID + " .comment.list").html(result);
    }});
}   

function partialSlide(divID) {
    var contentHeight = $("#"+divID+"").addClass('full').height();
        $("#"+divID+"").removeClass('full').animate({ 
            height: (contentHeight == $("#"+divID+"").height() ? 100 : contentHeight)
        }, 500);    
}
Community
  • 1
  • 1
Sinister Beard
  • 3,570
  • 12
  • 59
  • 95

2 Answers2

4

I think your issue might be that loadComments doesn't have a return so the promise is never given to the when.

function loadComments(divID,postID) {
    return $.ajax({url: "ajax-comments/?post_id=" + postID, success:      
    function(result){
        $("#" + divID + " .comment.list").html(result);
    }});
}   

As pointed out in the comments this line is calling partialSlide immediately since you have parentheses at the end. It should be:

$.when(loadComments(divID,postID)).done(function () { partialSlide(divID) });
AtheistP3ace
  • 9,611
  • 12
  • 43
  • 43
2

As already explained the comments there are multiple problems in the code like

  1. $.ajax() returns a promise object so there is no need to pass it to $.when()
  2. Since you want something to do after the ajax request in loadComments is completed, you need to return a promise from that. Since $.ajax returns a promise you can just return that value
  3. You need to pass a function reference to done(), when you do partialSlide(divID) you are actually calling the function partialSlide by passing the parameter and is passing the value returned from it(undefined in this case) as the done callback.

So

function loadFullPost(permalink, divID, postID) {
    $.ajax({
        url: permalink + "?ajax=true",
        success: function (result) {
            $("#" + divID + "").html(result);
            loadComments(divID, postID).done(function () {
                partialSlide(divID)
            })
        }
    })
}

function loadComments(divID, postID) {
    return $.ajax({
        url: "ajax-comments/?post_id=" + postID,
        success: function (result) {
            $("#" + divID + " .comment.list").html(result);
        }
    });
}

function partialSlide(divID) {
    var contentHeight = $("#" + divID + "").addClass('full').height();
    $("#" + divID + "").removeClass('full').animate({
        height: (contentHeight == $("#" + divID + "").height() ? 100 : contentHeight)
    }, 500);
}
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531