Let's say I have this express application and want to add a global variable at the top
import express from 'express';
const app = express();
// var globalScopeVariable = 123;
app.get('/', (req, res) => {
// home page
});
app.get('/create/:message', (req, res) => {
// add block
});
app.get('/add/:peerPort', (req, res) => {
// add peer
});
Would it be good practice to use 'var' or 'let' in this scenario?
In your case (Node.js), neither var nor let make a global scope variable; both will create a module-scope variable (accessible inside this module, but not in other modules). This may be what you want (in which case, let is generally preferred these days, and var should be consigned to history); but it case it isn't, the only way to make a true global scope variable is by direct assignment:
global.globalScopeVariable = 123;
If your variable can be reassigned, then use let otherwise use const. You don't have to bother about var anymore.
You can always consider the following powerful master rules around variable declaration in modern JavaScript.
Stop using var as soon as you can!
Use const whenever you can!
Use let only when you really have to!
Related
This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Closed 1 year ago.
For web browser I can do like this.
function action(){
GLOBAL_VAR = 3
}
let GLOBAL_VAR = 0
let funcName = 'action'
window[funcName]()
console.log(GLOBAL_VAR)
How I can do this for Node.js inside a module?
I'm not sure what your use case is, but doing this practice in a NodeJS environment is even worse practice than using globals in the browser, since atleast with browser specific code the namespace is distinct to the client's machine, but with NodeJS the global variable is stored in the Server memory, accessible to every request potentially.
You might unwittingly create race conditions and a bunch of problems-- maybe even ddoss your own server if you're continually adding data to the global object since it will eat up your heap memory.
You could use global constants, but having routes modify NodeJS globals seems a bit sketch.
If you insist, you would just use the "global" variable name that's accessible anywhere in your NodeJS Express app.
global.globalString = "This can be accessed anywhere!";
More defined example, index.js:
const express = require("express");
const app = express();
const globals = require('./globals');
const PORT = 3000;
//set the global var
global.var = 0;
global.action = function() {
console.log('running action');
return global.var = 3;
}
app.use('/globals', globals);
app.get('/', (req, res) => {
res.send("home route");
})
app.listen(PORT, () => {
console.log("app running on port: ", PORT);
console.log('global var: ', global.var);
})
Then in your routing file,
globals.js:
const express = require('express');
const router = express.Router();
router.get('/', function(req, res){
const action = 'action';
global[action]();
res.send('global route')
});
module.exports = router;
So yeah, just be sure to set the function and initial variable to the global object in your main app file first before you can use them in your routes. I'd still advise against this.
I'm having troubles with making a variable within a function global. This would work outside of the app.post('/init...) below
Here is my code:
const cloudlyn = require ('cloudlyn/demon')
app.post('/init', function(req, res){
cloudlyn.fly(customList, function(err, demonid){
if (err){
console.log(err)
}if (demonid){
console.log(demonid)
// everything works until this point.
userDemonid = demonid
// the problem is raising this variable to global scope.
// I understand not using const, var or let helps accomplish this
}
});
// then I have another function that needs this demonid.
// Notice that this is within the same app.post('/init'...)
const migrateCloudlyn = cloudlyn.migrate({
// I am trying to access the variable userDemonid
demonid = userDemonid,
plan = basePlan
}
});
The variable userDemonid is somewhat not available globally, any idea why this is so?
What am I doing wrongly?
You can use cookies or sub pages. Or debug function priority. "require()" function a interpreter. If defined a global function in 'cloudlyn/demon' it name is not your defined address. You can not import js code on DOM runtime. Try to access "cloudlyn.globalfoo".
I'm writing a node program and I want several functions contained in separate files to access and modify the same scope of variables without defining them in the global scope.
The solution I found is using a module to share its scope but it seems a bit tricky.
Here's the file tree :
- index.js
- file-a.js
- file-b.js
- shared-scope.js
index.js :
require('./file-a')
require('./file-b')
file-a.js :
const sharedScope = require('./shared-scope');
sharedScope.foo = 'bar'
file-b.js :
const sharedScope = require('./shared-scope');
console.log(sharedScope) // Prints { foo: 'bar' }
shared-scope.js :
module.exports = {};
What do you think about it? Is this a good way of sharing a scope between modules?
Sure, that's called a singleton. Some might say that any global, shared state is bad, but if that's what you want, this is a perfectly fine and simple way to do it.
The most obvious alternative is to define the data in one place and then in other modules, define functions which work on the data.
file-b.js:
module.exports = function (data) {
data.foo = "bar";
}
index.js:
const assignFoo = require('./file-b.js');
const data = {};
assignFoo(data);
For my user registration I have
const express = require ('express');
const userRouter = express.Router ();
userRouter.get ('/', function getUserList (req, res) {
let User = require ('../models').User;
User.find ({}, function (err, list) {
res.json (list);
});
});
userRouter.post ('/', function createUser (req, res) {
let User = require ('../models').User;
if (req.body.username && req.body.password)
User.create (req.body, function (err, user) {
res.json (user);
});
});
... 3 more functions with the same `let User` ...
module.exports = userRouter;
Here, I have to require the module models twice. I tried setting the User variable as a global variable up at the top of the program, like
const express = ..., userRouter = ...
var User = ...
However this User variable is still not accessible inside my callback functions.
Is requiring the User module multiple times the correct way to do this or am I missing something?
edit: Inside the callback functions, the User variable is undefined.
As #Doug mentioned, you should pass global to the user variable like this:
global.user = ...
This process essentially turns user into a globally accessible variable. You can read more about Node's global here to understand what it does as well as understand what it's implications are too: http://stackabuse.com/using-global-variables-in-node-js/
To #charloetfl ‘s point if it is just within the file, declaring it outside the callback or on top of the file should do. If we are talking about access across all modules and files within the project then adding it to the global object is the way to go about it in node as #doug and #andrewl mentioned.
This is probably me being stupid...
I'm using node with express and I have a seperate file using exports for routes. Above it, I require and cast to a variable, a package I have installed using npm.
var passwordHash = require('password-hash');
app.get("/signup", routes.signup);
inside routes.signup, I have:
passwordHash.generate(req.form.username, {algorithm: 'sha512'})
and it throwing an error saying passwordHash is undefined. How can I go about "inheriting" said require call?
You can also do the following (say this code is defined in app.js):
module.passwordHash = require('password-hash');
app.get("/signup", routes.signup);
in routes.signup:
var passwordHash = module.parent.passwordHash; // from app.js
passwordHash.generate(req.form.username, {algorithm: 'sha512'});
Separate files have separate scopes, so if you want to use passwordHash inside of your other file, then you need to call require('password-hash'); in that file too.
You can move your variables via app variable which should be accessible everywhere. Try to do something like that:
app.passwordHash = require('password-hash');
app.get("/signup", routes.signup);
The other thing that you might try is to use global variable, which means removing var from passwordHash. Not sure if this will work out for express, but it's worth checking.
passwordHash = require('password-hash');
app.get("/signup", routes.signup);
Let me know if it helped.
I know this question is old, but this would've helped me: Use exports!
So if I have a file called Index.js with this:
var model = require("./Model");
function test()
{
model.setMyVar("blah");
console.log(model.myVar);
}
My Model.js would look like this:
var myVar;
exports.myVar = myVar;
function setMyVar(value)
{
this.myVar = value;
}
exports.setMyVar = setMyVar;