Importing variables from another file on node is confusing - node.js

Hi,
I have a node server. This is what my init file looks like:
require("variables");
require("constants");
require("index");
app.get('/', function (req, res, next) {
res.sendFile(__dirname + '/index.html');
});
httpServer.listen(port, () => {
console.log(`server running`);
});
My variables file looks like this:
file = "file.json";
dataopen = "stuff";
userdata = "user";
module.exports={file,dataopen,userdata}
whereas my constants file:
const button = "<div></div>";
const title = "Page Title";
const input = "submit";
module.exports={button,title,input}
The thing here is that if I call for a variable inside index.js it will read it just fine:
console.log(dataopen); //it will output 'stuff'
but not so with any constants which will output undefined unless I include this line on top:
const { button,title,input } = require("constants");
why is that? Why do I need the extra line for constants but not for variables as well? I also noticed that by removing the prefix const before declaring then I wont need the line but why is that?
Thank you.

Do a console.log(global). Chance are that you will see your dataopen and the other vars.
In a nutshell, by not "declaring" a variable, it will implicitly be global. And when you try to access an undeclared variable, js regards it is a global variable. Something that is not allowed anymore in strict mode.
Should not be said, but global vars bad, do not use them.

Related

How to break a single node.js file into many?

Hi,
I have an app on node.js which consists of a single file app.js that looks like this:
//variables
app = require("express")();
//many more variables here
//functions
function dosomething {}
//many more functions here
but since its getting a little too long I would like to break it into several files, one for variables only (variables.js) and another one for functions only (functions.js) and load them from app.js like this like when you do it with php
//variables
include(variables.js);
//functions
include(functions.js);
is it even possible to do that? Or I have to include everything in one single file like I do now?
Thank you.
You can use Module.Export to export a separate file, and import it into another file using the require statement. Please check here for details:
https://www.geeksforgeeks.org/import-and-export-in-node-js/
Happy Learning :-)
Importing API Endpoints
You can do this by using app.use(...) and point each endpoint to a specific file like so:
const express = require("express");
const app = express();
// User Functions
app.use("/api/user", require("./routes/api/user"));
//Orders functions
app.use("/api/orders/", require("./routes/api/orders"));
/**
* Express Server Init
*/
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on ${PORT}`));
Then in /routes/api/user/user.js you would have something like:
const express = require("express");
const router = express.Router();
router.post("/create", (req, res) => {
try {
// Create user
} catch (error) {
console.log(error);
res.sendStatus(500);
}
});
module.exports = router;
Add and index.js inside /routes/api/user to point at the user file to keep things pretty when importing (otherwise you have to import it like /routes/api/user/user):
const user = require("./user");
module.exports = user;
Importing Single File
Not sure your use case but variables could be a bad naming convention since these values are more like constants than variables. Either way, you create it like this:
const variables = {
varibleOne: "valueOne",
varibleTwo: "valueTwo",
varibleThree: "valueThree",
};
module.exports = variables;
Then wherever you want to import it you can do:
const variables = require("./variables");
and access it like so variables.variableOneand so on.
Importing functions
You can also import different functions, say you need a file called helper.js where these are commonly functions needed all over you app, you could do something like this:
const twoDecimals = (number, decimal = ",") => {
let val = (Math.round(number * 100) / 100).toFixed(2);
return decimal === "." ? val : val.replace(".", decimal);
};
const getRandomInt = (max) => {
return Math.floor(Math.random() * Math.floor(max));
};
module.exports = { twoDecimals, getRandomInt };
Then wherever you needed you can import it by:
const { twoDecimals } = require("helper.js");
Now you have access to your helper functions anywhere.
You should get help from the JavaScript modular system (preferably COMMONJS).
For example, suppose we have two files:
1-module.js 2-app.js
So now let's create this files
module.js
let name = "hello world";
function printSomething(message) {
console.log(message)
}
//here export all function and variable
module.exports.name = name;
module.exports.printSomething = printSomething
ok so Well now it is enough that "require" this file in main file :
main.js
// we
const {name, printSomething} = require("./module.js");
printSomething(name);
for export all variable You need to create an object and specify your variables as a property:
let host = "localhost"
let dbname = "laravel_8"
let username = "root"
let password = "root"
function doSomething() {
console.log("hello");
}
module.exports = {host, dbname, username, password, doSomething}
so in main file :
const variables = require("./module.js")
//host
let host = variables.host
//dbname
let dbname = variables.dbname
//function doSomething
let doSomething = variables.doSomething;
doSomething()
// or directly
variables.doSomething()
In fact, in php we use the "->" symbol to access properties, and in JavaScript we use "."

Node convert variable value to variable name for use in destructuring assignment

I have a models folder with an index.js file that looks like the following:
'use strict';
const {Dest1} = require('./destinations/dest1');
const {Dest2} = require('./destinations/dest2');
module.exports = {Dest1, Dest2};
I would like to dynamically load these objects based on a condition. I was thinking it might be interesting to have a middleware function that appends a value to the request that I could use to look up the correct object. I could just dynamically load the path, but I'm curious if this is possible.
Middleware:
function checkDestination(req,res,next){
if('destination1' in req.body){
req.path = 'Dest1'
}
next()
}
Router:
router.get('/', checkDestination, (req,res)=>{
//convert req.path to variable name here
const {Dest1} = require('./models')
})
Symbols?
Ok, decided to go with a hashtable or dictionary look up to avoid repeating a bunch of if statements. If the above is possible, it would be less code but this is pretty clean too.
Middleware:
function checkDestination(req,res,next){
if('destination1' in req.body){
req.destination = 'destination1'
}
next()
}
HashTable:
const {Dest1} = require('../models')
const destLookUp = {
destination1:function(destObj){
return Dest1.create({})
.then(newDest=>return newDest})
.catch(error=>{console.log(error)})
}
}
module.exports = {destLookUp}
Router:
destLookUp[req.destination](destObj)

How to modify variable in one file from another

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

global variable in node using coffeescript

I checked this How do I define global variables in CoffeeScript?
for declaring a global variable i.e., declaring in the app.js and accessing in the routes/index.coffee
I declared (exports ? this).db = redis.createClient() in the app.coffee and tried to access the db in the routes.index.coffee using db.set('online',Date.now(), (err,reply) -> console.log(reply.toString()) ) this doesn't seem to work...what is happening..I am on node 0.8.9
There are other approaches in which it works but curious to know what is happening...
Also tried the #db = redis.createClient() in the app.coffee which doesn't work either
Thanks
exports doesn't define "globals;" it defines "public" members of a module available via require. Also, exports is always initially defined and exports === this, so (exports ? this) isn't actually doing anything.
However, since globals are generally frowned upon (and do defeat some of the intents of Node's module system), a common approach for web applications is to define a custom middleware allowing access to the db as a property of the req or res objects:
# app.coffee
app.use (req, res, next) ->
req.db = redis.createClient()
next()
# routes/index.coffee
exports.index = (req, res) ->
req.db.set('online', Date.now(), (err,reply) -> console.log(reply))
An example of this can be found in decorate.js of npm-www, the repository behind npmjs.org:
function decorate (req, res, config) {
//...
req.model = res.model = new MC
// ...
req.cookies = res.cookies = new Cookies(req, res, config.keys)
req.session = res.session = new RedSess(req, res)
// ...
req.couch = CouchLogin(config.registryCouch).decorate(req, res)
// ...
}
Though, if you'd still rather define db as a global instead, Node.JS defines a global variable you can attach to:
global.db = redis.createClient()

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