0

Trying to get data from the inner loop, but getting with delay.

In the code, I am getting the user list from the sql table with their ancestors. I need these ancestors to check their root values(hierarchy/tree structure). If the ancestor role is salesmanager, then add salesmanager name for each user.

Case which is not working:

If a user itself is parent, value pushes into array. (WORKS)

If a user has parent (like user_id 3 is added by user_id 2, and 2 is added by 1), 1 is ancestor of 3. Goes to inner loop.

Value pushes to the same array, displays if prints inside this array but didn't display if prints outside the loop

Here is the code:

var sql_query='SELECT *,GetAncestry(id) as anstry FROM users'  //get ancestors using sql function
con.query(sql_query, function(err,rows) {
    if(err) throw err;
    if(rows) {
        console.log('length rows'+rows.length) // prints 5
        var rows_salesinfo=[]
        var ancestors=[]
        rows.forEach(function(rows) {
            if(rows.anstry !='') {
                var array = JSON.parse("[" + rows.anstry + "]");
            } else {
                var array = []
            }
            if(array.length > 0) {
                // inner loop starts
                con.query('SELECT id,role,firstname,lastname FROM users WHERE users.id IN ('+array+')', function(demoErr,demoRows) {
                    if(demoErr) throw demoErr;
                    if(demoRows.length > 0) {
                        var keepGoing = true;
                        demoRows.forEach(function(index,value,callback) {
                            if(keepGoing) {
                                if(index.role == 'sales_manager') {
                                    console.log(rows.id)
                                    rows.salesmanager = index.firstname+" "+index.lastname
                                    rows_salesinfo.push(rows)
                                    keepGoing = false;
                                }
                            }
                            console.log(rows_salesinfo) // this inner loop values print here
                        })
                    } else {
                        rows_salesinfo.push(rows)
                    }
                })
            } else {
                console.log(rows.id) // works
                rows.salesmanager=''
                rows_salesinfo.push(rows) // works
            }
        })
        console.log('6new')
        console.log(rows_salesinfo) // works before response of inner loop
        console.log('length rows_salesinfo'+rows_salesinfo.length) // length 3 
    }
})
Community
  • 1
  • 1
Simerjit Parmar
  • 808
  • 1
  • 7
  • 22
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – GilZ May 29 '17 at 15:21

1 Answers1

0

Your inner loop is inside callback function. So, it will be executed only after con.query will be executed on db level and returns a result. .query is asynchronous function. You could read about callbacks and node.js event loop here. Basicly, query command looks like this "hey, db, execute this command please, and tell me, when result is ready. After that I'm going to execute my callback function." And while db is running your query, javascript command keep executing. If you want last logs to be executed after all queries will be ready, I'd suggest you to take a look at async.each function.

So, your code will look like this

async.each(rows, 
           function(row, callback) {
               // Perform operation on row that you need
               //run innex query and inner loop
               con.query('some query', function(demoErr,demoRows) {
                   if(demoErr) callback(demoErr); //error will apear in final function
                   //demo rows foreach and if here
                   callback(); //execute callback without args to show that this function is finished
               });
           }, 
           function(err) {
               //check for err here 
               //and do final logs
               console.log('6new')
               console.log(rows_salesinfo)
               console.log('length rows_salesinfo'+rows_salesinfo.length) 
           });

You will need to run

npm install --save async

in your project directory