In my index.js I require a config file for connection strings etc, like this:
var config = require('./config');
config.js then does:
module.exports = config;
so in index.js I can use the properties off config like config.db_connect_string.
When I also require for instance db.js to do the database stuff, how can I access properties of config within the functions I create in db.config and export back to index.js?
Hope this makes sense! I'm starting out with node.
I don't know what db.js looks like, but you should be able to inject the config object into the db.js module from your index.js file, and then use curried functions to create the db object you want to export.
Like so:
At index.js
var config = require('./config');
var { makeDB } = require('./db');
var db = makeDB(config)
At db.js
module.exports.makeDB =
// Pass in the expected config object
function(config) {
// If your db module needs parameters
// you can pass them in here
return function(){
// Create db module here.
// The properties of the config object
// passed in will be available here.
// Be sure to return the database object.
return db;
}
}
Related
I am writing an application that has configuration parameters in a json file. Something like this:
// config.json
{
"httpServer": {
"port": 3000
},
"module1": {
"setting1": "value1",
"setting2": "value2"
},
"module2": {
"setting1": "value1",
"setting2": "value2"
}
}
// index.js
const config = require("./config")
const func1 = require("./module1")
const func2 = require("./module2")
// code here
// module1.js
const config = require("./config")
// use config and define functions
module.exports = {
function: function
}
// module2.js
const config = require("./config")
// use config and define functions
module.exports = {
function: function
}
The problem is that I am requiring this file in every module which makes my code unmaintainable since I need to update every require statement if the filename changes. I am pretty sure that this is not the "correct" way of doing this. Can I require the configuration file once when the program starts and then reference to it in other modules? Or should I pass the configuration file as a command line argument and then use process.argv array when requiring the file? What is the best way of handling situations like these?
use dotenv package npm install dotenv --save,
create a config file
//config.env
NODE_ENV=development
IP=127.0.0.1
PORT=3000
load the config file
//index.js
const dotenv = require('dotenv');
dotenv.config({ path: './config.env' })
use it where ever you want
//module1
console.log('IP: ',process.env.IP)
To be honest I don't really see anything wrong in requiring the config in multiple files. Since you need it, you are requiring it.
If you really don't want to require multiple times, you could consider this
Convert the function style to class style and then inject the config as a dependency to that class
Main File
const config = require("./config");
const file1 = new File1(config);
const file2 = new File2(config);
File 1
class File1 {
constructor(config) {
this.config_ = config;
}
someFunction() {
// use this.config_ here
}
}
File 2
class File2 {
constructor(config) {
this.config_ = config;
}
someFunction() {
// use this.config_ here
}
}
Few advantages of using this approach are:
better testable as you can mock the config if you want.
you could also change at one place and you wouldn't need to change other places as you are injecting.
//in app.js
var x = require("x.js");
var instanceX = new x();
require("./Weather")();
//in Weather.js
instanceX.getName();
In this case instanceX wouldn't exist when referenced from Weather.js. How do I make instanceX accessible in Weather.js?
There are a number of different ways to approach this in module design. One simple way is to just pass the variable to the weather.js constructor:
//in app.js
var x = require("x.js");
var instanceX = new x();
require("./Weather")(instanceX);
//in Weather.js
var instanceX;
module.exports = function(ix) {
instanceX = ix;
}
// then elsewhere in the module
instanceX.getName();
I refer to this as the "push" model because you're pushing things to the module that you want to share with it.
I'm new to nodejs. I have the following files and code:
// file: myfunc.js
function myfunc() { return "myfunc()"; }
exports = myfunc;
and
// file: index.js
var mf = require("./myfunc");
var mfunc = mf();
console.log(mfunc);
When I run node index.js from command line, I get the error
var mfunc = mf()
^
TypeError: Object is not a function
Why do I get this error? I saw someone else's code which I paste below and I tried to follow the same approach of trying to get require() to return a function instead of an object.
// file: index.js from another app
var express = require('express');
var app = express();
How come require('express') can return a function but require('./myfunc') can't return a function?
It should be...
module.exports = myfunc;
... instead. Quoting the doc:
If you want the root of your module's export to be a function (such as
a constructor) or if you want to export a complete object in one
assignment instead of building it one property at a time, assign it to
module.exports instead of exports.
I am pretty certain there is a way to pass a variable using require.
So it would look something like this:
var model = require('model')(mongoose);
With the above line of code, I want to pass my model file my database information (mongoose), so that if I access the same model with a different database, I can pass it different database information.
However, even if the above syntax is correct, I am not sure what my model file itself would have to look like. Can anyone help me out with this?
module.exports = function (mongoose) {
// . . .
return model;
};
You can pass moongoose by argument to that file
var model = require('model')(mongoose);
Your module will look like this, you can make an object in module.exports and can attach multiple properties to that object and in the end return it from the function
module.exports = function (mongoose) {
model ={};
model.properties = {};
model.yourfunction1 = function(){};
return model;
};
I guess I can't assign anything else to module.exports in this case?
Answer to your comment is explained below
Choosing between module.exports and exports depends on you
For exports
exports.object1 = {};
exports.object2 = {};
For module.exports
module.exports = function(){
myobj={}
myobj.object1 = {};
myobj.object2 = {};
return myobj
}
Now calling it will be different
For exports it will be directly available on file variable
var file = require('./file');
console.log(file.object1);
For module.exports you will execute it like a function by appending function parenthesis so that object can be returned
var file = require('./file')();
console.log(file.myobj.object1);
I'm running some issues with my node application after upgrading to Express 3.0. So, since I'm rewriting it, I was trying to follow the style of routes/index.js because it looks clean.
So, in my main app.js I have some variables such as:
var calls = 0;
var agents = [];
And also use the node-mysql module. However, the routes definition doesn't have app.js scope but their own scope so calls and agents aren't visible.
How should I make them visible?
For mysql I tried something like:
// libraries/mysql.js
mysql = require('mysql');
var mysql_conf = {
host: myhost,
user: myuser,
password: mypass,
database: mydb
};
var mysql_client = mysql.createClient(mysql_conf);
exports.mysql_client;
//Later in routes/index.js
mysql_client = require('../helpers/mysql.js');
But it seems not to work as it says TypeError: Object #<Object> has no method 'query'
Any hints please?
The line
exports.mysql_client;
Does not actually assign anything to the mysql_client property of exports. It accesses a property, and immediately discards the value. You need to do something like this:
var mysql_client = mysql.createClient(mysql_conf);
exports.mysql_client = mysql_client;
// or simply
exports.mysql_client = mysql.createClient(mysql_conf);