codeyashu codeyashu - 1 month ago 7
Node.js Question

Export functions or variables to another module in node.js

I know there are lots of questions similar to mine but I could not find the best solution.
I am creating a web app with node and rethinkdb. I want to organise different js files (modules) so that each has specific task.
I have this query.js file whose query result must be passed to routes.js file.
I have tried implement this in the following way.

query.js



//dependencies
var express = require('express');
var path = require('path');
var r = require('rethinkdbdash')({
port: 28015,
host: 'localhost',
db: 'stocks'
});


var len;

//function to get companies list
exports.clist = function(){
r.table('company')
.run()
.then(function(response){
return response;
})
.error(function(err){
console.log(err);
})
}
console.log(exports.clist[0].id)

//function to get number of entries in database
exports.clen = function(){
r.table('company')
.run()
.then(function(response){
len = Object.keys(clist).length;
return len;
})
.error(function(err){
console.log(err);
})
}





routes.js



//dependencies
var express = require('express');
var request = require('request');
var path = require('path');
var r = require('rethinkdbdash')({
port: 28015,
host: 'localhost',
db: 'stocks'
});

//query module
var query = require('./query')


clist = query.clist();
clen = query.clen();


//create router object
var router = express.Router();

//export router
module.exports = router;

//home page
router.get('/', function(req, res) {
console.log('served homepage');
res.render('pages/home');
});


//--companies page--//
router.get('/company', function(req,res){

console.log('served companies page')
res.render('pages/company', {
clist: clist,
x:clen
});
});





the console log in query.js is showing that cannot read property id of undefined.

Also I would like to know is there a way to directly pass the variables instead of using functions and then calling it.
I apologise if the solution is obvious.

To summarise I want the query result which is an object to be accessible from routes.js file.

Answer

Note: As exports.clist1 is an asynchronous method, you can't expect the result to be printed in the next line, hence comment this line and follow as below

//console.log(exports.clist[0].id)

You have to register a middleware to make this working, otherwise, query will be called only at the time of express server started and not at every request.

So you can do like this,

Hope you had something like this in your startup file (app.js),

var app = module.exports = express();

routes.js

//query module
var query = require('./query')
var app = require('../app');  // this should resolve to your app.js file said above

//clist = query.clist();
//clen = query.clen();

// middleware to populate clist & clen
app.use(function(req, res, next){
   query.companyList(function(err, data){
      if(!err) {
         req.clist = data.clist;
         req.clen= data.clen;
      }
      next();
   });
});

query.companyList(function(err, data){
      if(err) {
         console.log(err);
      } else {
         console.log(data.clist[0].id);
         console.dir(data.clist);
      }
   });


//create router object
var router = express.Router();

//export router
module.exports = router;

//home page
router.get('/', function(req, res) {
    console.log('served homepage');
    res.render('pages/home');
});


//--companies page--//
router.get('/company', function(req,res){  

      console.log('served companies page')
      res.render('pages/company', {
        clist: req.clist,
        x: req.clen
      }); 
});

Change your query.js like this,

//function to get companies list 
exports.companyList = function(next){
    r.table('company')
.run()
  .then(function(response){
     var list = {
       clist: response,
       clen: Object.keys(response).length
     };
     next(null, list);
  })
 .error(function(err){
    console.log(err);
    next(err);
 })   
};