0

The following code is to generate bulletin board list. It works fine for viewing contents (eg, postId0, postId1, ...) but works as if 'i' were nPosts

I recall that in C# I had the same problem and fixed by declaring a copy of i (var copy_i = i; inside the loop), but here that didn't work either.

function loadList() {
    $.getJSON("list.php", function (json) {
        var nPosts = json.length;
        for (var i = 0; i < nPosts; i++) {
            var post = $('<ol/>', {
                class: "viewPost",
                id: "post" + i
            }).appendTo("#viewList");

            $('<li/>', {
                class: "viewPostId",
                id: "postId" + i,
                text: json[i].noteId
            }).appendTo("#post" + i);

            var memo = $('<li/>', {
                class: "viewMemo",
                id: "memo" + i,
                text: json[i].noteContent
            }).appendTo("#post" + i);

            //alerts 'nPosts' for every i.
            memo.on("click", function () { alert(i); });
        }
    });
}
1
  • I'm reading through the code now, but as a preliminary question: are you familiar with the concept of closures (and how counter variables can also be closed over)? Usually questions about strange behavior in loops arise from neglecting closures. Commented Nov 26, 2013 at 3:38

2 Answers 2

2

As expected, the problem was with an unforeseen closure. This line:

memo.on("click", function () { alert(i); }); 

creates a closure over the i variable, which is incremented all the way to the maximum value before your click handler is ever invoked.

Here is how you would provide a "dummy variable" for your handler to close over:

var handlerCreator = function (counter) { 
    return function(){
        alert(counter); // The handler now closes over the counter variable, 
                        // which cannot be accessed by other code and therefore
                        // retains the value passed in to this function (i.e. the
                        // value of i on the current iteration)
    }; 
}
memo.on("click", handlerCreator(i));
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! So the dummy variable method don't work in js and should always define function creator. I thought there might be some simpler workarounds.
1

The click functionality that alerts i is executed after the loop is complete thus it will be equal to nPosts

Comments

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.