Node.js for() loop returning the same values at each loop


Question

I'm making this really simple application to help me explore nodejs and I have a particular handler that generates HTML code based on the top10 messages in my database. The snippet I'm having problem with loops through the messages and call the function generating HTML and appends the result to my html string.

function CreateMessageboard(BoardMessages){
  var htmlMessageboardString = "";

  [... Console debug code ...]

  for(var i = 0; i < BoardMessages.length;i++){
        (function(){
            var j = i;
            console.log("Loading message %d".green, j);
            htmlMessageboardString += MessageToHTMLString(BoardMessages[j]);
          })();
  }
}

I think my problem is due to either Javascript's way of handling loops, related to closures from what I read and this is what I tried using above or the async way nodejs handles my function. Right now the 10 results are well returned from the db but the last message is processed at every loop.

I also tried, instead of doing var j = i, to take value i as function parameter and pass it in the closure and it returned the same results anyway.

I have a feeling I'm missing critical knowledge to solve my problem, can I get light on this matter ?

Edit : I'm welcome to give any other info on the code, I'd post the whole git repo but people probably don't want to swim through a whole project to help me debug this issue so I posted the whole function in the comments to provide more context.

1
13
1/24/2014 4:01:28 PM

Accepted Answer

  for(var i = 0; i < BoardMessages.length;i++){
        (function(j){
            console.log("Loading message %d".green, j);
            htmlMessageboardString += MessageToHTMLString(BoardMessages[j]);
        })(i);
  }

That should work; however, you should never create a function in a loop. Therefore,

  for(var i = 0; i < BoardMessages.length;i++){
        composeMessage(BoardMessages[i]);
  }

  function composeMessage(message){
      console.log("Loading message %d".green, message);
      htmlMessageboardString += MessageToHTMLString(message);
  }
24
4/19/2012 7:45:40 PM

I would suggest doing this in a more functional style :P

function CreateMessageboard(BoardMessages) {
  var htmlMessageboardString = BoardMessages
   .map(function(BoardMessage) {
     return MessageToHTMLString(BoardMessage);
   })
   .join('');
}

Try this


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon