How to access global scope variables in callback functions? [JS] - javascript

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.

Related

Make a Javascript variable in a function global

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

Parsing JavaScript code in Node.js module

// ===============================================================================
// Auth
// ===============================================================================
const admin = require('firebase-admin'); //what happens if i move this line
admin.initializeApp(); //and this line
module.exports = function(app) {
//to this line
//and this line?
app.post('/login', function(req, res) {
const token = req.body.token;
console.log('token sent: ' + token);
admin
.auth()
.verifyIdToken(token)
.then(result => {
console.log('verifyIdToken result: ' + result);
});
res.send({ valid: 'havent programmed this yet' });
});
};
Let's say I'm working with the above code. I am curious why it still runs if I place the first lines of code:
const admin = require('firebase-admin');
admin.initializeApp();
from the outside of the anonymous function that module.exports to inside of it? I am so confused! Is this function looking outside of its module to grab this scope, and what is the difference in declaring this admin const from within module.exports rather than outside of it?
To understand what is happening, you need to understand Javascript Closures and Module Pattern.
When the two lines are outside the module.exports, they are part of the global scope and hence visible to your module. This is because variables defined outside any function, block, or module scope have global scope inside the file.
When you move it inside the module, they become part of function/ module's scope and hence again visible.
You can read this old but relevant article to get a better understanding.
https://www.joezimjs.com/javascript/javascript-closures-and-the-module-pattern/

Expressjs middleware keeps variable changed

I am trying to do a simple thing which is obvious I believe in the code below:
module.exports = function(req, res, next) {
var dop = require('../../config/config').DefaultOptions;
console.log(require('../../config/config').DefaultOptions);
console.log(dop);
dop.firstPage = 'test.sjs';
next();
};
This is an Expressjs middle ware which is very simple but the interesting point is that next time I load a page both of the console.log results has been changed to 'firstPage: test.sjs'. It shouldn't act like this and it should only change the dop variable.
Anyone with the knowledge why this creepy thing is happening?
Thank you
The main issue is require() is cached, so require('../../config/config') returns reference to the same instance, and as a result changing in one place causes all other references and subsequent requires to get that modified instance.
The simplest solution would be have a function in config to return a config object, that way every time invoking the get config function you will get a new instance with essentially the same content. I.e.:
config.js:
module.exports = {
getDefaultOptions: function(){
return {foo: 'bar', ip: '1.1.1.1'}
}
};

Should you use 'var' or 'let' in the global scope?

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!

Express - Passing mysql connection to scripts

I defined mysql connection with all parameters necessary to app.js, how can make visible to other scripts in routes/ by default, without requiring or redefining mysql parameters, just using client.query(..)?
A pattern I use is to set up my db object in a module once and export it: (let's call it utils/mySQL.js)
//I haven't used real mysql in node so excuse the pseudo-syntax:
var db = require('mysql-driver-thingy');
db.connect('localhost', 'sqlport', options...);
db.otherSetupFunctions();
console.log("Finished db setup. You should only see this message once! Cool.");
module.exports = db;
And then I can require the db object everywhere I need it. Since requires are cached, this does't actually call the setup methods multiple times.
In app.js:
var db = require('./utils/mySQL.js');
...
In models/user.js:
var db = require('../utils/mySQL.js');
...
A final option, which isn't recommended, is to pollute the global namespace. This seems to be the answer you're really after:
//set up your db
...
// and now make it available everywhere:
global.client = db.client
You can now magically use the client object in all your modules, without even requiring it.
There are many reasons globals are bad, though:
If your code and other code define globals, they could conflict and overwrite each other.
It's hard to find where you defined the db/client object, etc.
You can inject mysql connection into other scripts like this:
app.js
var mysqlConnection = new Conection(params);
require('controller/main.js)(mysqlConnection);
main.js
module.exports = function(mysqlConnection) {
// You can access your mysql connection here
};
UPDATE:
You can inject several variables same way. Also you still can export methods from module if you need this:
app.js
var mysqlConnection = new Conection(params);
var news = require('model/news.js)(app, mysqlConnection);
news.list(function(err, news) {
// Do something
});
news.js
module.exports = function(app, mysqlConnection) {
var methods = {};
// mysql connection and app available from here
methods.list = function(cb) {
mysqlConnection.list(function(err, data) {
cb(err, data);
});
};
return methods;
};

Categories

Resources