judlup
judlup

Reputation: 139

How to make a nested queries on mysql with Node.js?

I'm trying to make a nested queries with mysql on Node.js with Express, the result should be a json with three nested, the problem is that the return doesn't show me the third nested, my code is:

app.get('/devices/:id', ensureToken, function(req, res){    
    jwt.verify(req.token, jwt_secret, function(err, data) {
        if (err) {
          res.sendStatus(403);
        } else {
            var segment_id = req.param('id');

        //Select devices for segment        
        var ls_devices = 'SELECT d.device_id AS id, d.device_name AS name, d.device_serial AS serial, d.device_description AS description, d.device_key AS keyatom, d.device_type AS type_id, dt.device_type_name AS type, d.device_user_id AS user_id, u.user_name AS username, d.device_segment_id AS segment_id, sg.segment_name, d.device_public AS isPublic, d.device_status AS status FROM ((g_devices d LEFT JOIN g_user u ON u.user_id = d.device_user_id) LEFT JOIN g_device_type dt ON dt.device_type_id = d.device_type) LEFT JOIN g_segments sg ON sg.segment_id = d.device_segment_id WHERE d.device_status = 1 AND sg.segment_id = '+segment_id;
        connection.query(ls_devices, function (error, results, fields) {
                  if (error) throw error;
                  if(results.length != 0) {                                                     
                      var j = JSON.parse(JSON.stringify(results));
                      var i = 0;
                      var d = [];
                    j.forEach(function(r,index_r){                        
                          //
                          var ls_controllers = 'SELECT c.device_controller_id AS id, c.device_controller_name AS name, c.device_controller_description AS description, c.device_controller_devcon_type AS type_id, ct.devcon_name AS type, ct.devcon_description AS description, d.device_name AS device, d.device_id AS device_id, d.device_serial AS serial, c.device_controller_public AS public, c.device_controller_date_register AS registered, c.device_controller_date AS date, c.device_controller_status AS status  FROM (g_device_controller c LEFT JOIN g_device_controller_type ct ON ct.devcon_id = c.device_controller_devcon_type) LEFT JOIN g_devices d ON d.device_id = c.device_controller_device_id WHERE c.device_controller_status = 1 AND d.device_id = '+r.id;
                          connection.query(ls_controllers, function (error_c, results_c, fields_c) {                            
                            var k = JSON.parse(JSON.stringify(results_c));
                            d.push({device:r.name,controller:[]})
                            k.forEach(function(r2,index_r2){                                                                        
                                d[index_r].controller.push({name:r2.name,action:[]})
                                var ls_actions = 'SELECT a.action_id AS id, a.action_name AS name, a.action_description AS description, a.action_type AS type_id, aty.action_type_name, aty.action_type_description AS type_description, a.action_controller_device_id AS device_id, a.action_control AS control, a.action_value AS value, a.action_time AS time, a.action_times AS times, a.action_date AS date, a.action_status AS status  FROM g_actions a LEFT JOIN g_action_type aty ON aty.action_type_id = a.action_type WHERE a.action_controller_id = '+r2.id;
                                  connection.query(ls_actions, function (error_a, results_a, fields_a) {                                    
                                    if(results_a.length > 0) {
                                        var l = JSON.parse(JSON.stringify(results_a));
                                        l.forEach(function(r3, index_r3){                                                                                                               
                                            d[index_r].controller[index_r2].action.push({id_a:r3.id,name_a:r3.name});                                           
                                            console.log(JSON.stringify(d))
                                        });                                     
                                    }                                   
                                });
                            });                                           
                            i ++;                           
                            if(i == j.length)
                            {                               
                                return res.json(d); 
                            }                           
                          });                         
                    })
                }
              else {
                return res.json({devices:false});   
              }         
            }); 
    }
    });     
});

My web response is:

[
    {
        "device": "device one",
        "controller": [
            {
                "name": "device controller One",
                "action": []
            }
        ]
    },
    {
        "device": "device two",
        "controller": []
    }
]

And the print of the last array push is:

[ { "device": "device one", "controller": [ { "name": "device controller One", "action": [ { "id_a": 1, "name_a": "device action One" } ] } ] }, { "device": "device two", "controller": [

]

} ]

Upvotes: 0

Views: 1548

Answers (1)

Cody Geisler
Cody Geisler

Reputation: 8617

k.forEach() does not wait for connection.query() to finish, so effectively the queries are skipped. The remedy is to do something similar to what you did with j.forEach(), but i++ should not happen until all of those finish too.

(Other notes: you could use promises, or async/await and make the flow appear much more neatly, or if you want to stick with learning callbacks you could use async library to simplify some of this)

Upvotes: 1

Related Questions