views:

56

answers:

2

First question on stackoverflow :) Hope I won't embarrass myself...

I have a javascript function that loads a list of albums and then it creates a list item for each album. The list item should be clickable, so I call jQuery's click() with a function that does stuff. I do this in a loop. My problem is that all items seem to get the same click function, even though I try to make a new one that does different stuff in each iteration. Another possibility is that the iteration variable is global somehow, and the function refers to it. Code below. debug() is just an encapsulation of Firebug's console.debug().

function processAlbumList(data, c) {
 for (var album in data) {
  var newAlbum = $('<li class="albumLoader">' + data[album].title + '</li>').clone();
  var clickAlbum = function() {
   debug("contents: " + album);
  };
  debug("Album: " + album + "/" + data[album].title);
  $('.albumlist').append(newAlbum);
  $(newAlbum).click(clickAlbum);
 }
}

Here is a transcript of what it prints when the above function runs, after that are some debug lines caused by me clicking on different items. It always prints "10", which is the last value that the album variable takes (there are 10 albums).

Album: 0/Live on radio.electro-music.com
Album: 1/Doodles
Album: 2/Misc Stuff
Album: 3/Drawer Collection
Album: 4/Misc Electronic Stuff
Album: 5/Odds & Ends
Album: 6/Tumbler
Album: 7/Bakelit 32
Album: 8/Film
Album: 9/Bakelit
Album: 10/Slow Zoom/Atomic Heart
contents: 10
contents: 10
contents: 10
contents: 10
contents: 10

Any ideas? Driving me up the wall, this is. :)

/Stefan

+1  A: 

You need to introduce another scope, such as like this:

var clickAlbum = (function (a) {
    return function () {
        debug("contents: " + a)
    };
})(album);
Sean
Marvellous! Thanks a lot. I had a feeling this was one of those stupid newbie things but I was going insane...
TV's Frank
A: 

The album variable in your inner function is a closure, however its value is not bound when each function is declared. That means that each time through the loop, the album closure will be changed to the value it has in that loop. There is a more detailed explanation here

As Sean (and the article) suggest, you can solve this problem by changing the scope of the variable.

Justin Ethier
Yep Sean's suggestion made everything work. I was actually trying to change the scope by assigning stuff to a local variable in the function (and a myriad of other crazy attempts), but now I know better. Thanks for the link - I'm going to check it out.
TV's Frank
You're welcome. Because the root cause is fairly advanced, it might be helpful for you to read over to get a deeper understanding...
Justin Ethier