Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 949
Tristan Dubé Avatar asked Apr 19 '12 18:04

Tristan Dubé


2 Answers

  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);
  }
like image 104
Joe Avatar answered Nov 07 '22 01:11

Joe


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

like image 45
ming_codes Avatar answered Nov 07 '22 01:11

ming_codes