1

I am executing a mysql query inside a for loop, this loop is in callback function but when i do console.log(i), it shows me 3 three times. below is the code. I am using async.parallel, I am only posting the code which is having the problem. Also res is returning fine but obj is showing the third record three times, instead it has to show obj1 data, obj2 data, obj3 data. console.log(i) is the example response.

function(user,callback){               
                for(var i = 0; i < user.length ; i++) {                 
                    var obj = user[i];
                    mySQLConn.mySQLDBConnection.query('select id,name from table where type = ?',[obj.id],function(err,res){
                        console.log(i); //This shows 3 three times      
                        obj.type = res;
                        userJSONArray.push(obj);                       
                    })
                }

            }

What I want it should print 1,2,3 instead of 3,3,3. Any help is really much appreciated.

JN_newbie
  • 5,492
  • 14
  • 59
  • 97

2 Answers2

1

ES6: This problem can now be solved with the let keyword.

function(user, callback) {
  for (let i = 0; i < user.length; i++) {
    let obj = user[i];
    mySQLConn.mySQLDBConnection.query('select id,name from table where type = ?', [obj.id], function(err, res) {
      console.log(i); //This shows 3 three times      
      obj.type = res;
      userJSONArray.push(obj);
    })
  }
}

Actually your callback is working properly.

Your db query is most likely asynchronous. Which means that by the time you get the information from your database, i already equals 3.

You could eventually make it synchronous: Synchronous database queries with Node.js

kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
0

This is because of the asynchronous calls. By the time your calls finish i has 3 in it...You could do something like this:

for(var i = 0; i < user.length ; i++) {                 
    var obj = user[i];
    (function(i, obj)
    {
        mySQLConn.mySQLDBConnection.query('select id,name from table where type = ?',[obj.id],function(err,res){
            console.log(i); //This shows 3 three times      
            obj.type = res;
            userJSONArray.push(obj);                       
        })
    })(i, obj);
}
brso05
  • 13,142
  • 2
  • 21
  • 40
  • Thanks for the answer, this for loop then should be in callback rite? – JN_newbie Feb 17 '16 at 19:26
  • Thanks. Can I call another callback function when for loop finishes? If yes where should I call? When for loop finishes? something like callback(null,userJSONArray); – JN_newbie Feb 17 '16 at 19:30
  • It says function name expected so I did it function execQuery(i,obj){}(i,obj) – JN_newbie Feb 17 '16 at 19:33
  • @Java_NewBie you're welcome! Well that is kind of tricky. You don't know when your last `mySQLConn.mySQLDBConnection.query` will finish. And you don't know which one will finish last...It really depends on how you want to design it. – brso05 Feb 17 '16 at 19:33
  • @Java_NewBie ya that is fine... – brso05 Feb 17 '16 at 19:34
  • Thanks once again. I just need one clarification about this syntax function execQuery(i,obj){}(i,obj). Can you please explain a little It would be great? – JN_newbie Feb 17 '16 at 19:36
  • @Java_NewBie Basically you are declaring a function and calling it right away instead of waiting and later calling `executeQuery(i, obj);`. Each function invocation has its own instance of `i` and `obj` so it won't always be 3 it will be whatever was passed in...Google closures for more information. – brso05 Feb 17 '16 at 19:39
  • Thanks. really helpful – JN_newbie Feb 17 '16 at 19:41
  • @Java_NewBie no problem...I messed up the syntax I am going to fix it hang on. – brso05 Feb 17 '16 at 19:41
  • @Java_NewBie ok i updated...notice the extra `()` around the anonymous function. If you do that you shouldn't need a name... – brso05 Feb 17 '16 at 19:42
  • `(function(i, obj)` and `})(i, obj);` – brso05 Feb 17 '16 at 19:43
  • I am trying it out now – JN_newbie Feb 17 '16 at 19:53
  • Yes Thanks it worked by adding () around the anonymous function :) – JN_newbie Feb 17 '16 at 19:55