Make a Javascript variable in a function global - javascript

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

Related

How to add value to global object from module in Node.js

I'm trying to add some value to the global or local object, but nothin happens.
I'm tried create:
global.test = {}; in main.js
And to add value test[name] = value in second js
tried create var test = {}; in second.js
And to add value test[name] = value in second js
But this examples doesn't helped me.
Code in my files:
main.js:
global.common = require('./second.js');
global.test = {}
second.js:
module.exports = {
main: function (name, value) {
test[name] = value;
}
};
second.js invoked in another files, but the whole point is displayed in the code above.
Reading the NodeJS docs:
In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module.
Seems like you are expecting the global scope of NodeJS to work the same way that JS works in browsers but that is not the case.
See this question for more information : What is the 'global' object in NodeJS

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!

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

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.

Javascript global variable undefined in function scope

I am new to JavaScript and trying to make a simple node server. Here is my code:
var activeGames = {}
exports.initialize = function(){
var gameID = "game12345"
activeGames.gameID = new Game(gameID, "player1", "player2")
}
I call the initialize function from another module, and I get an error stating that activeGames is undefined. activeGames is at the outermost scope of the file. I tried adding 'this' before activeGames.gameID but that did not fix it. Why is activeGames undefined? Thanks in advance.
EDIT: Here's how I'm calling this code.
In my base index file I have
const handler = require("./request-handler.js")
handler.initialize()
In request-handler.js, I have
var gameManager = require('./game-manager')
exports.initialize = function(){
gameManager.initialize()
}
JavaScript has lexical scope, not dynamic scope.
ref: https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping
Lexical scope means that whether a variable is accessible or not depends on where they appear in the source text, it doesn't depend on runtime information.
example:
function foo() {
var bar = 42;
baz();
}
function baz() {
console.log(bar); // error because bar is not in the scope of baz
}
the same problem happens in your code,
var activeGames
is not in scope.
try this variation:
exports.initialize = function(){
var activeGames = {}
var gameID = "game12345"
activeGames.gameID = new Game(gameID, "player1", "player2")
}
A good solution could be to use a class and export it:
--THIS CODE IS NOT TESTED--
class gamesManager {
var activeGames = {}
initialize() {
var gameID = "game12345"
activeGames.gameID = new Game(gameID, "player1", "player2")
}
}
exports.gamesManager = gamesManager
USE:
const activeGames = require('./game-manager');
const activeGamesInstance = new activeGames.gamesManager();
activeGamesInstance.initialize();
Need a code sample for this one. I ran this locally and it worked fine, although your code has a big issue which may be a part of your problem. It looks like you want to keep track of multiple games in activeGames. You need to use this syntax instead:
activeGames[gameID] = new Game(gameID, "player1", "player2")
Here's my working code:
index.js:
const handler = require("./request-handler");
handler.initialize('game-1234');
handler.initialize('game-5678');
request-handler.js:
var gameManager = require('./game-manager');
exports.initialize = function(gameID) {
gameManager.initialize(gameID);
}
game-manager.js:
var activeGames = {};
class Game {
constructor(id, player1, player2) {
this.id = id;
this.player1 = player1;
this.player2 = player2;
}
}
exports.initialize = function(gameID) {
activeGames[gameID] = new Game(gameID, "player1", "player2");
console.log(`game initialized! ${ Object.keys(activeGames).length } active games`);
}
Running node index results in this:
game initialized! 1 active games
game initialized! 2 active games
When you require a script file in Node.js, it is compiled as part of a function called with named parameters require, module, exports and other exposed variables as arguments1. Variables declared at file level within the required script become function level variables in the enclosing module wrapper and retained inside its closure.
Hence your "global variable" is no such thing: it's a variable defined inside a closure...
An important question then is does the module loader make variables declared in a parent module available to scripts required inside the parent. A quick test shows that the answer is general: no, modules do not have automatic access to variables declared in other modules - those variables are inside closures.
This indicates that to pass variable values to scripts that have been required, generally pass them as argument values to exported functions.
It is also possible to export any javascript value as a property of module.exports from within a required script, or add properties to an exports object after it has been returned from requiring a script. Hence it is technically feasible to pass information up and down between modules by adding properties to exports objects.
Redesigned code has multiple options to
define activeGames at the application level and pass it down as a parameter to modules needing access to it, or
export activeGames from game-manager.js by adding
exports.activeGames = activeGames
to the end of the file. This will not take care of exporting activeGames out of the parent module request-manager.js for use elsewhere, but it could be a start. Or
define activeGames as a global variable (in node) using
global.activeGames = {} // define a global object
Defining global variables is not encouraged as it can lead to collisions (and consequent program failure) between names used by applications, code libraries, future library updates and future versions of ECMAScript. Or,
Define an application namespace object for data global to the application. Require it wherever access to application data is needed:
create appdata.js as an empty file.
Optionally include a comment:
// this files exports module.exports without modification
require appdata.js wherever needed.
var appData = require('./appdata.js')
appData.gameData = {}; // for example
This relies on node.js maintaining a cache of previously required modules and does not recompile modules simply because they have been required a second time. Instead it returns the exports object of the previous require.
Happy festive season.
References
1The Node.js Way - How require() Actually Works

Meteor variable is not defined

This Meteor server code is complaining
Exception in callback of async function: ReferenceError: myConn is not defined
The variable myConn is defined in ddp.js and is used in method.js,
Any idea why and how to fix it? thx
//server/ddp.js
let myConn = DDP.connect('http://localhost:5000');
//server/method.js
myConn.call('myMethod', {obj}, () => {})
let limits the variable's scope to the block or statement in which it is used.
var defines a variable locally to an entire function or procedure.
To define a variable globally and accesible between multiple files avoid using let or var and just assign a default value to its name. Example:
myVarName="";

Categories

Resources