Issue with scope and passing parameters to dynamically created event handler
dom-events, javascript
Solution
Yet another problem solved by closures!
image.onclick = function(id, section_id){
return function(event) {
deleteImage(event,id,section_id);
}
}(id, section_id);
The outer function is run at once (notice the parentheses with arguments at the end), and it returns the inner function, which keeps in its scope a copy of the variables as they are at that iteration of the loop.
JavaScript passes non-object variable by value, so by passing `id` and `section_id` to the outer function, you create a copy of them inside that function. When you create and return the inner function, that inner function keeps in scope all variables that are in scope at the time of its creation (this is at the heart of what a closure is), including the local-variable copies of `id` and `section_id`. The inner function, with its unique scope, becomes the event handler for that element.
Problem
In the code below you will see that I am trying to define an event handler for `image.onclick` which takes extra parameters, I was declaring those parameters inside of the while loop hoping JavaScript defined scope this way but it does not. Basically all of the event handlers here are getting the very last value that I give to variables `id` and `section_id`. Any idea on how to handle a situation where i want to be generating these handlers dynamically? ``` function handlePicturesResult(){ if (req.readyState == 4) { // Complete if (req.status == 200) { // OK response var el = document.getElementById('pictureHolder'); while( el.hasChildNodes() ){ el.removeChild(el.lastChild); } var tempObject = JSON.parse(req.responseText); var pictures = tempObject.images; var i=0; while(i<pictures.length){ var picIndex = i; var image= new Image(120,80); image.src = 'images/' + pictures[i].url; image.width = 120; image.height = 80; var id = pictures[picIndex].id; var section_id = pictures[picIndex].sectionId; image.onclick = function(event){ deleteImage(event,id,section_id); } var txtNode = document.createTextNode(pictures[picIndex.valueOf()].id); el.appendChild(image); el.appendChild(txtNode); i++; } } else { alert("Problem: " + req.statusText); } } } ```