0

I am trying to load comments and their replies from my database.

To do this, I need to know which replies need to be added after which comments.

I tried doing this with an iterator, assigning i to each new comment as an id and trying to then add all corresponding replies to the pertinent "#"+i Sadly this does not work as you can see in the output of the console.logs:

ITERATOR: 1
ITERATOR: 2
ITERATOR: 3
ITERATOR: 4

ANSWER ITERATOR: 4
ANSWER ITERATOR: 4
ANSWER ITERATOR: 4
ANSWER ITERATOR: 4

All replies are added under comment with id of 4.

Which is not what was expected obviously.

What is causing this and how do I fix it ?

(I add the replies using insertAfter($("#"+i));)


var i = 0;
    var postKey = "<%= post.key %>";
    var commentsRef = firebase.database().ref("comments/"+postKey).orderByChild('commenttimestamp').limitToFirst(25);
    commentsRef.once("value", function(snapshot) {
        snapshot.forEach(function(childSnapshot){
            i++;
            console.log("ITERATOR: "+i);

                $("#commentsBox").prepend("<div class='fullComment' id='"+i+"'><a href='../../users/"+childSnapshot.val().author+"'><div class='userCommentBox'><div class='commentUsername'>"+childSnapshot.val().username+"</div><img class='userPic' src='https://storage.googleapis.com/gaminghub-upload/"+childSnapshot.val().profilepic+"' /></div></a><div class='comment'>"+childSnapshot.val().text+"</div><div><img data-post='"+postKey+"' data-comment='"+childSnapshot.key+"' data-author='"+ childSnapshot.val().author +"' class='commentCross' src='./../../public/assets/cross.png'><img class='replyIcon' data-comment='"+childSnapshot.key+"' data-author='"+ childSnapshot.val().author +"'  src='./../../public/assets/replyIcon.png'></div></div>");
                var that = $(this);
                var answersRef = firebase.database().ref("comments/"+postKey+"/"+childSnapshot.key+"/answers");
                answersRef.orderByChild("answertimestamp").once("value", function(answersSnapshot) {
                    answersSnapshot.forEach(function(answer) {
                        if (answer.val().profilepic == undefined || answer.val().profilepic == null || answer.val().profilepic == "") {
                            $("<div class='answer'><a href='../../users/"+answer.val().author+"'><div class='userCommentBox'><div class='commentUsername'>"+answer.val().username+"</div><img class='userPic' src='../../../public/assets/miniProfilePic.png' /></div></a><div class='comment'>"+answer.val().text+"</div><div><img class='answerCross' data-post='"+postKey+"' data-comment='"+childSnapshot.key+"' data-answer='"+answer.key+"' data-author='"+ childSnapshot.val().author +"' src='./../../public/assets/cross.png'></div></div>").insertAfter($("#"+i));
                        } else {
                            console.log("ANSWER ITERATOR: "+i);
                            $("<div class='answer'><div class='userCommentBox'><a href='../../users/"+answer.val().author+"'><div class='commentUsername'>"+answer.val().username+"</div><img class='userPic' src='https://storage.googleapis.com/gaminghub-upload/"+answer.val().profilepic+"' /></div></a><div class='comment'>"+answer.val().text+"</div><div><img class='answerCross' data-post='"+postKey+"' data-comment='"+childSnapshot.key+"' data-answer='"+answer.key+"' data-author='"+ childSnapshot.val().author +"'  src='./../../public/assets/cross.png'></div></div>").insertAfter($("#"+i));
                        }
                    });
                });
            }
TheProgrammer
  • 1,409
  • 4
  • 24
  • 53

1 Answers1

0

This seems to relate to JavaScript closure inside loops – simple practical example as pointed out by @wostex. A resolution was to put below the line

var that = $(this);

the line

let j=i

and then append j to answer iterator with

console.log("ANSWER ITERATOR: "+j);
Jeremy Kahan
  • 3,796
  • 1
  • 10
  • 23