How to modify variable in one file from another - node.js

My log.js,
var data ;
var winston = require('winston');
var config = {'status':1};
module.exports.config = config;
My get.js file(from where i want to modify log.js),
exports.getcategories = function (req, res) {
if(log.status == 1){
var data = 'loaded successfully';
}
};
Here i want to modify my data variable in log.js from my get.js,can anyone please suggest help.

You need to read up on Javascript scopes. In order to access any variable in a file or function from outside it, there are only two ways:
Make the variable global (NOT a good idea).
Create getter/setter functions and export them, thereby exposing it to the outside world

Related

NodeJS requiring modules, module.exports.X vs module.exports={x}

I'm having trouble understanding the difference between exporting modules like:
module.exports.getUserIP = function getUserIP(req) {
var ip = req.headers['x-forwarded-for'];
return ip;
}
Or just declaring it:
function getUserIP(req) {
// retrieve user IP from req object
// Build this function to be more accurate/use more sources.
var ip = req.headers['x-forwarded-for'];
return ip;
}
and exporting at the bottom:
module.exports = { getUserIP }
or even:
module.exports = {getUserIP:getUserIP}
or
module.exports = {'getUserIP':getUserIP}
My problem is: when i call the function getUserIP from another file:
var mainbody = require('./app.js');//getUserIP is in here.
const gl = require('geoip-lite');
var ax = require('axios');
module.exports.getloc = function getloc(req, ip, property) {
//return location from IP.
if (req) {
var ipGuest = mainbody.getUserIP(req); //HERE
} else {
var ipGuest = ip;
}....
I get an error message:
Error Message
However, when I use the FIRST method to export the function:
module.exports.getUserIP = function getUserIP(req) {
var ip = req.headers['x-forwarded-for'];
return ip;
}
Then it works perfectly.
What's the difference?
Better way is to use
module.exports = { getUserIP: getUserIP }
This way you can just look at the export statement at the end of your file and know which functions are being exported from a particular file
The module.exports = {getUserIP}; is nothing but a shorthand of the above syntax(ES6 Magic). What it typically does is allows you to write this way { getUserIP } if the key name to be same as function/variable name like { getUserIP: getUserIP } where getUserIP can be a variable or a function or a ES6 class.
All the examples you show will work properly, but they do have some different affects.
By default module.exports is already initialized to an empty object. So, when you do something like this:
module.exports.getUserIP = function() {...}
You are assigning a new property to the existing object that module.exports already pointed to. One advantage of this scheme is that you can easily add more properties the same way.
module.exports.getUserRegion = function() {}
This will add one more property to that same object without disturbing the first one you already added.
On the other hand, all of these are identical:
module.exports = {getUserIP: getUserIP}
module.exports = {'getUserIP':getUserIP}
module.exports = { getUserIP } // ES6 shorthand for the previous syntax
and, they all end up with the same result as each other, but they all replace module.exports with a new object that has your one new property in it.
If you then tried to add another property:
module.exports = {getUserRegion};
That would again assign a whole new object to module.exports and you would have just wiped out the object that previously had getUserIP on it. When assigning a new object, you would typically assign an object that had all your properties on it:
module.exports = {getUserIP: function() {...}, getUserRegion: function() {...}};
Thus, not wiping out something you had already put there.
All of your schemes should work fine as long as you aren't overwriting module.exports with a new object and thus overwriting the object that already had some of your methods on it.
To understand this exporting modules concept, just think module.export is a simple object. you can bind anything to that object as do with normal javascript objects.
Finally when you require that module by require('path to js') you will get that exported object. If you export number of items in your module you can return them back by giving the names of the tag.

node.js share dynamic variables between modules

I have a variable named number_of_clusters which must be updated periodically. number_of_clusters must also be shared with other modules to read it. how can I assure that reading modules will read a fresh copy of this variable each time they access that?
I dont want to use database to share this variable so I thought I could share it via process.env
process.env.number_of_clusters = 1;
is it a good practice?
Seems like your searching for a global variable:
global. number_of_clusters = 1
However using a database or a file would probably be a nicer solution.
Try reading/writing in a file?
var fs = require('fs');
fs.writeFile("/path/to/file", "whatever", function(err) {
console.log("The file was saved!");
});
fs.readFile('/path/to/file', 'utf8', function(err, contents) {
console.log(contents); // -> whatever
});
If the other modules are running as part of the same Nodejs process,
you can just export a getter to other modules which will get the fresh value of number_of_clusters for them.
Like:
function get_number_of_clusters() {
return number_of_clusters;
}
module.exports = { get_number_of_clusters };
Now in other modules, you need to import this module and call this method, like:
var getter = require('path/to/above/module').get_number_of_clusters;
var number_of_clusters = getter();
You could use socket.io to store the variable on the server and have it emit to all pages.

Access variable in main node file from an imported file

//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.

Node.js - passing object with require

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);

How to use global variable in node.js?

For example I want to use custom logger:
logger = require('basic-logger'),
logger.setLevel('info')
var customConfig = {
showMillis: true,
showTimestamp: true
}
var log = new logger(customConfig)
How to use this logger in other modules instead of console.log ?
Most people advise against using global variables. If you want the same logger class in different modules you can do this
logger.js
module.exports = new logger(customConfig);
foobar.js
var logger = require('./logger');
logger('barfoo');
If you do want a global variable you can do:
global.logger = new logger(customConfig);
global.myNumber; //Delclaration of the global variable - undefined
global.myNumber = 5; //Global variable initialized to value 5.
var myNumberSquared = global.myNumber * global.myNumber; //Using the global variable.
Node.js is different from client Side JavaScript when it comes to global variables. Just because you use the word var at the top of your Node.js script does not mean the variable will be accessible by all objects you require such as your 'basic-logger' .
To make something global just put the word global and a dot in front of the variable's name. So if I want company_id to be global I call it global.company_id. But be careful, global.company_id and company_id are the same thing so don't name global variable the same thing as any other variable in any other script - any other script that will be running on your server or any other place within the same code.
you can define it with using global or GLOBAL, nodejs supports both.
for e.g
global.underscore = require("underscore");
or
GLOBAL.underscore = require("underscore");
I would suggest everytime when using global check if the variable is already define by simply check
if (!global.logger){
global.logger = require('my_logger');
}
I've found it to have better performance
Global variables can be used in Node when used wisely.
Declaration of global variables in Node:
a = 10;
GLOBAL.a = 10;
global.a = 10;
All of the above commands the same actions with different syntaxes.
Use global variables when they are not about to be changed
Here an example of something that can happen when using global variables:
// app.js
a = 10; // no var or let or const means global
// users.js
app.get("/users", (req, res, next) => {
res.send(a); // 10;
});
// permissions.js
app.get("/permissions", (req, res, next) => {
a = 11; // notice that there is no previous declaration of a in the permissions.js, means we looking for the global instance of a.
res.send(a); // 11;
});
Explained:
Run users route first and receive 10;
Then run permissions route and receive 11;
Then run again the users route and receive 11 as well instead of 10;
Global variables can be overtaken!
Now think about using express and assignin res object as global.. And you end up with async error become corrupt and server is shuts down.
When to use global vars?
As I said - when var is not about to be changed.
Anyways it's more recommended that you will be using the process.env object from the config file.
If your app is written in TypeScript, try
(global as any).logger = // ...
or
Object.assign(global, { logger: // ... })
However, I will do it only when React Native's __DEV__ in testing environment.
May be following is better to avoid the if statement:
global.logger || (global.logger = require('my_logger'));

Resources