4

I am trying to run the following code:

I pass parameter to a function, but it always has the value of the last object run through the loop. I read some articles about it on stackoverflow, but I couldn't find out how to make it run in my solution.

The object is a JSON object returned from the server. All it's values are correct.

for(var i = 0;i<parents.length;i++){
            var row        = $(document.createElement("tr"));
            var colName    = $(document.createElement("td"));

            var aDisplayCol = $(document.createElement("a"));

            var parentId = parents[i]['PARENT_ID'];

            aDisplayCol.attr("href","#").html(parents[i]['NAME']);
            aDisplayCol.bind('click',function(){ alert(parentId);});


            colName.append(aDisplayCol);

            row.append(colName);
            $('#pages tbody').append(row);                

}

Thanks

3 Answers 3

8

It is a scope problem. By the time the event handler function is executed, the value of parentId has changed and is not longer what you expected.

This can be solved making the original event handler function be returned by another function which, in turn, is passed the value of parentId as argument:

function getEventHandlerFunction(id){
    return function() {
        alert(id);  // variable found in the closure with the expected value
    };
}


aDisplayCol.bind('click', getEventHandlerFunction(parentId));
Sign up to request clarification or add additional context in comments.

Comments

2

Perhaps there's a problem with using parentId in the callback.

Try alert(parents[i]['PARENT_ID']);.

EDIT: Let's see if we can get around our scope issues with .data().

aDisplayCol.data("parentId",parents[i]['PARENT_ID']);
aDisplayCol.click(function() {
   alert($(this).data('parentId'));
});

4 Comments

Nope, that's not causing it. Actually, I discovered yesterday that the .click function can't handle the following: aDisplayCol.click(function(){ whatever(target,dest, parents[i]['PARENT_ID']); return false; }); I assume it is a bug. Passing a variable instead works fine.
Nah I don't think it's a bug. I think it's a scope issue. I don't think i exists within the scope of the click handler.
you forgot to close the parenthesis at .data
using .data worked! AWESOME :D thanks. It is a closure problem.
1

You can avoid the clouseres problems with the eventData parameter of the bind function like this

var message = 'Spoon!';
$('#foo').bind('click', {msg: message}, function(event) {
    alert(event.data.msg);
});
message = 'Not in the face!';
$('#bar').bind('click', {msg: message}, function(event) {
    alert(event.data.msg);
});

this is from the jquery bind api documentation http://api.jquery.com/bind/#passing-event-data

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.