-1

I am new from Node js , just i am trying implementing this functionality last few days but i am unable to fix

exports.get_exercises_for_trainer = function(req, res)
    {

                connection.query('SELECT * FROM ag_exercise', function(err, exercise)
                 {


                    console.log('------------------------------before add fields ----------------------------------');
                    console.log(exercise);

                    for (var i in exercise)
                  {

                        fields(exercise[i].wt_id, function(result1) {


                                    exercise[i].wt_fields = result1; //here i am adding result set of other query but i am not geting this fields data

                                    console.log(result1) //but i printed here working fine but i need this result1 data out side query 

                          });

                    }

                    console.log('------------------------------after add fields ----------------------------------');
                    console.log(exercise);
                    res.render('pages/trainer_home.ejs',{page_title:"Exercise Create",exercise:exercise});

                    });


          }

        function fields(wt_id,callback) 
        {
            connection.query('SELECT *  FROM ag_workout_type_fields  WHERE wt_id = "'+wt_id+'"', function( err1, result1){

                  callback(result1);

             });

             }

I have one more query ? in node js : If table having users , users having different relation tables like orders , profiles , address

How to implement this

First i am getting users
User loop
getting every user profiles ,address,orders
end user loop

but above scenario i am unable to implement in node js but in php very simple like this

$get_users = ... //users data

foreach($getusers as $usr)
{

 $usr->orders = //orders data
.... like etc 
} 
user2964333
  • 104
  • 1
  • 1
  • 7

1 Answers1

2

There are three main questions here, I will adress each seperately.

Question 1: When making an async function, how do I then access my data outside that function?

All data from async calls are accessed via callback, event listeners or promises (a fancy callback and event listener handler). For the most part, you are going to just be using callbacks. So, instead of :

get_user = function(user_id){
    //Do some stuff to get the user
    return the_user;
};
var user = get_user('1234');
//do whatever you want with user

You will see :

get_user = function(user_id,callback){
    //Do some stuff to get the user
    callback(null,the_user);
}
get_user('1234',function(err,user){
    //do whatever you want with user
});

When we get to Question 3, you will see the more complicated use case you were speaking of.

Question 2: How do I loop through my data, perform a subsiquent query on each row, and append that data to my current data?

There are a couple of issues here.

  1. Every time you query the database, you are performing an asynchronous function, so you need to manage all of those callbacks accordingly. Fortunately there are some great tools to do that for you, and we will be using async.
  2. Every time you call an asynchronous function in a for loop, the for loop continues, thus your iterator is overwritten, but your asynchronous function is not done with it yet, so you will get all sorts of unexpected results like vanishing variables, or missmapped results. You can handle this with JavaScript closures, or, you can rely again on libraries like async which handle it all for you.

Instead of running a for loop over your queries results, we're going to pass it to async.forEachOf, which we will use to modify the existing array and append the results of the subsequent queries to the primary query's rows. It is important to note that forEachOf will run the subsequent queries in parallel, so you should not be using a single database connection, but a pool. If you MUST use a single database connection, use forEachOfSeries instead.

async = require('async');
exports.get_exercises_for_trainer = function(req, res){
    connection.query('SELECT * FROM ag_exercise', function(err, exercises)
    {
        console.log('------------------------------before add fields ----------------------------------');
        console.log(exercises);
        async.forEachOf(exercises,function(exercise,index,callback){
            connection.query('SELECT * FROM ag_workout_type_fields WHERE wt_id = "' + exercise.wt_id + '"', function( err, result1){
                if(err)return callback(err1);
                exercises[index].wt_fields = result1; //Modify original array
                return callback();
            });
        },function(err){
            if(err){return;} //do some error handling
            console.log('------------------------------after add fields ----------------------------------');
            console.log(exercises);
            res.render('pages/trainer_home.ejs',{page_title:"Exercise Create",exercise:exercises});
        });
    });
};

Question 3: How do I perform many related but different queries so that I can populate information about my object?

This is another great usage of the async library. In this case since the queries are all different, we'll use parallel instead of forEachOf.

async = require('async');
populate_user = function(user,_callback){
    async.paralell({
        profile: function(callback){
            var sql = "SELECT * FROM profiles WHERE user_id = " + user.id + " LIMIT 1 ";
            var connection.query(sql,function(err,rows,fields){
                if(err)return callback(err);
                if(rows.length === 1)return callback(null,rows[0]);
                return callback(null,[]);
            });
        },
        address: function(callback){
            var sql = "SELECT * FROM addresses WHERE user_id = " + user.id + " LIMIT 1 ";
            var connection.query(sql,function(err,rows,fields){
                if(err)return callback(err);
                if(rows.length === 1)return callback(null,rows[0]);
                return callback(null,[]);
            });
        },
        orders: function(callback){
            var sql = "SELECT * FROM orders WHERE user_id = " + user.id;
            var connection.query(sql,function(err,rows,fields){
                if(err)return callback(err);
                if(rows.length > 0)return callback(null,rows); //notice how this one could have multiple results so we're returning them all
                return callback(null,[]);
            });
        },
    },
    function(err,result){
        if(err)return _callback(err);
        for(var att in result){user[att] = result[att];}
        callback(null,user);
    }
}
user = {id:1234};
populate_user(user,function(err,populated_user)){
    console.log(user); //wow notice how it's populated too!
    console.log(populated_user); //this is really just a new handle for the same object
});

I want to note that NONE of this was tested, not even for syntax, so it may take a little reworking.

trex005
  • 5,015
  • 4
  • 28
  • 41