Global scoped variable not accessible - javascript

Merged with Can't access variable (array) from another function (defined in global scope).
NOTE: this is not an async problem. This question was closed prematurely. I am reposting and answering so the OP has an answer that is useful.
I'd like to use a variable (array) from another function. I already defined it in global scope, but it doesn't work..
Here is my code for better understanding:
var globalData = '';
var data = '';
$.getJSON('https://...' + data[x].id + '.json', function(data) {
globalData = data;
data = globalData.name;
console.log(data); // works just fine
if (condition === 1) {
function2(); // calls this function
} else {
function3();
}
});
function function2() {
console.log(data); // just an empty line
console.log(globalData); // UPDATE: works just fine
}

Related

Shared variable in Javascript files returns stale value

I have 2 javascript files. I want to create a shared a variable that will be created in file 1 but can be used in 2nd file. The shared variable is initialize with a certain value but then updated with some other value in file 1. Since file 2 is called after the updation of variable in file 1 , I am expecting it to have the latest value but it always gives me the stale value. This is what I have tried.
file 1
var myVar ='100';
//assume updateMyVar function exists which will return a callback with the value that needs to be updated
updateMyVar('someKey', function(result)
{
//let's assume the result came back as someValue
console.log("inside callback " + result);
myVar = result;
});
module.exports.myvar = myvar;
file 2
var file1 =require('./file1');
var myvar = file1.myvar;
//expecting myvar to be someValue instead of 100
console.log(myvar);
Its better to define a getter for it.
In file1.js
const getMyVar = ()=>{
return myVar;
}
module.exports.getMyVar = getMyVar;
file2.js
var {getMyVar} =require('./file1');
console.log(getMyVar());
As of now,
module.exports.myvar = myvar;
this statement provide one-time binding with current value myvar;
So, there is no updated value whenever you fetch it after update .
Hope this helps:
// Use some kind of Module pattern to achieve this in a proper manner.
const X_MODULE = (() => { // Anonymous function
this.myVar = 100;
updateMyVar('someKey', (result) => {
//let's assume the result came back as someValue
console.log("inside callback " + result);
this.myVar = result;
});
return this;
})(); // IIFE -> Immediately Invoked Function Expression.
module.exports = X_MODULE;
// OR make use of one of the OOPs Singleton Class Pattern
class X_MODULE {
constructor() {
this._myVar = 100;
// I've kept this call just for demonstration purpose.
updateMyVar('someKey', (result) => {
//let's assume the result came back as someValue
console.log("inside callback " + result);
this._myVar = result;
});
}
get myVar() {
return this._myVar;
}
}
module.exports = new X_MODULE(); // Singleton Pattern: will have only one instance throughout the app lifecycle.
Both approach will give you the exact same result.

return javascript variable from inside callback function

I am trying to get client.get to return the reply value so it can be used globally.It keeps saying undefined.any suggestions
var redis = require("redis");
var websocket= require("websocket");
var valuewanted;
websocket.on('message', function(data) {
if (data.type == "purchase" && data.price > 0) {
console.log("==========================================================");
console.log(data );
console.log("==========================================================");
client.get(p1, function(err, reply) {
var valuewanted = reply;
console.log(reply);
});
});
the console.log logs the value but if i try to log valuewanted it doesnt work.
Drop the var within the client.get function:
client.get(p1, function(err, reply) {
// valuewanted already defined above
valuewanted = reply;
console.log(reply);
});
If you use var within a function, it becomes scope-blocked to that function.
From mozilla:
The scope of a variable declared with var is its current execution
context, which is either the enclosing function or, for variables declared outside any function, global.
In this case, using var within that function redefines it within that function, and its scope becomes "the enclosing function". Hope this helps.

Why is my function not returning the array? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
This is my code:
document.getElementById('revealUser').onclick = displayDaUsers
function displayDaUsers(){
pullAllUsersFromDB();
debugger;
}
function pullAllUsersFromDB(){
rootRef.child('users').on('value', function(snapshot) {
var users_array = [];
var users_object = snapshot.val();
Object.keys(users_object).map(function(key) {
users_array.push(users_object[key]);
});
// window.dateApp.allUsers = users_array;
return users_array
});
}
html:
<input type="submit" id="revealUser" value="reveal user">
I put a debugger in to see the problem but it does not help. When I go into the console and type in users_array
I get Uncaught ReferenceError: users_array is not defined(…)
NEW CODE (EDIT):
according to another stackoverflow answers this should work..
function displayDaUsers(){
var test = pullAllUsersFromDB();
console.log(test);
//pullAllUsersFromDB();
//debugger;
//setUpFirstUser()
}
function pullAllUsersFromDB(){
rootRef.child('users').on('value', function(snapshot) {
var users_array = [];
var users_object = snapshot.val();
Object.keys(users_object).map(function(key) {
users_array.push(users_object[key]);
});
//window.dateApp.allUsers = users_array;
return users_array
});
}
The return value users_array is local to the scope of the anonymous callback function function(snapshot) {.... In other words, its value is lost outside of that scope.
At what point in your logic do you need access to user_array? If you need access to it outside of the context of your functions, maybe it makes sense to define a variable with greater scope, and then setting its value in your anonymous function. E.g.
document.getElementById...
var arr;
...
function pullAllUsersFromDB() {
...
...function(snapshot) {
arr = users_array;
});
}
// pullAllUsersFromDB() (and its callback) must be called for arr to be defined at this point in execution

JS Function returning function for later use - arguments undefined

I am trying to create a function that can then return many functions based on an input. Here is an example of the problem I am facing.
var giveFunction = function(text) {
return function(text) {
console.log(text)
}
}
var test = giveFunction('this is a test');
test()
Running test() at the end prints undefined instead of 'this is a test.' Is there any way around this problem?
The inner function should not contain any parameter,
var giveFunction = function(text) {
return function() {
console.log(text)
}
}
Let it create a closure. If it has a parameter then that would be read during execution and undefined would be printed as you are not calling that function with any arguments.
If you want your code to be working then you have to use bind for that,
var giveFunction = function(text) {
return function(text) {
console.log(text)
}.bind(null, text)
}
var test = giveFunction('this is a test');
test(); //'this is a test'
Lets go one step further and ask why?
var outerFunction = function(outerParameter) {
return innerFunction function(innerParameter) {
// in here we have access to anything in this function and the outer function
// all the way to out the the global scope
// therefore, we dont need to pass innerParameter in again as a parameter! ( in your case we 'next')
}
/// now over here, outside of innerFunction, we do NOT have access to innerParameter!
}
So applying the above principles to your code we have:
var giveFunction = function(text) {
return function() {
console.log(text)
}
}
var test = giveFunction('this is a test');
test()
which now works!
Finally, checkout the most upvoted post under the javascript tag:
How do JavaScript closures work?

javascript closures getting variable out and wrong context [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 7 years ago.
what is correct way of writing this in js?
notice this.signals.total is in a wrong context.
articleSchema.pre('save', function(next) {
if (!this.publisher) {
this.publisher = this.url;
}
social.facebook(this.url, function(err, signals) {
//problem is this
this.signals.total = signals.total_count;
});
if (!this.weight) {
this.weight = 1440;
}
var currentDate = new Date();
this.updated_at = currentDate;
if (!this.created_at) {
this.created_at = currentDate;
}
next();
});
this in that case refers to social.facebook correct?
There are several ways I could deal with the problem, e.g. create outside variable, but what is js way?
A simple solution is to store a reference to the correct context:
articleSchema.pre('save', function(next) {
// ...
var that = this; // Store a reference to `this`.
social.facebook(this.url, function(err, signals) {
// Use `that`.
that.signals.total = signals.total_count;
});
// ...
});
Yes, a common solution is to assign the this pointer to a variable outside the inner function like this:
var self = this;
function foo() {
// this would not work, but self does
}
In ECMA-Script 6, you can also use an arrow function instead.
social.facebook(this.url, (err, signals) => {
// this will point to the outer this
});
See this article for more details:
It is totally depends on how the callback is called.
1/ this will be global.
social.facebook = function(url, fn) {
fn(url)
}
2/ this will be social
social.facebook = function(url, fn) {
fn.call(this, url)
}
This way this can also be something weird:
social.facebook = function(url, fn) {
fn.call(weirdObject, url)
}
Create outside variable like the others answer is one way, the other one is bind.
social.facebook(this.url, function(err, signals) {
//problem is this
this.signals.total = signals.total_count;
}.bind(this));

Categories