Access "variable" environment variable using dynamic javascript variable names - javascript

I have an issue. In my Host/cloud solution, I must use environment variables of pricing for each country this way 'defined in their "Environment Variables").
BASIC_PRICE_FR_PRODUCT = "50";
COMPLEX_PRICE_FR_PRODUCT = 100;
BASIC_PRICE_UK_PRODUCT = "37";
COMPLEX_PRICE_UK_PRODUCT = "200";
BASIC_PRICE_ES_PRODUCT = "75";
COMPLEX_PRICE_ES_PRODUCT = "300";
I can access those using process.env.XXX such as process.env.BASIC_PRICE_FR
As you see these environment variables depend on the country as the price vary from one country to the other.
In our node.js app, the challenge is that when a function is executed, it is self aware of the country so, we can (and must) use the "current" country and the current country_iso_code ("fr" for example), and with this we must use the pricing that match this country.
After reading on SO some posts on "dynamic variable names" , I tried eval, global[] and window[] like below, but none work and all outputs "undefined" values
//note: iso_code_3166_we_can_use is something passed to the function by the final user or by some other lambda in the function context.
const current_country_iso_code_uppercase = iso_code_3166_we_can_use;
const basicPrice = parseInt( "process.env.BASIC_PRICE_" + current_country_iso_code_uppercase + "_PRODUCT")
console.log(basicPrice)//bug here as outputs "undefined"
EDIT
The suggestion of using process.env['xxx'] did not work so I add here the results
console.log(process.env.BASIC_PRICE_FR_PRODUCT);//outputs 50
console.log('BASIC_PRICE_' + iso_code_uppercase + '_PRODUCT' );//just to be sure :): outputs BASIC_PRICE_FR_PRODUCT
console.log( process.env['BASIC_PRICE_' + iso_code_uppercase + '_PRODUCT'] );// DOES NOT WORK, outputs undefined

Use [] to dynamically access an object's property:
var country = 'FR'
var price = process.env['BASIC_PRICE_' + country + '_PRODUCT']

//Create an empty dictionary,
var process_env_dict = {};
process_env_dict['env'] = process.env;
//then you can access it with the below statement as you expected
var result = JSON.parse(JSON.stringify(process_env_dict))['env']['BASIC_PRICE_' + country + '_PRODUCT'];

Related

Pass a parameter into a function and have that function generate a variable name that contains the passed parameter?

Hi I am fairly new to Javascript.
I am trying to pass a parameter into a function and have that function generate a variable name that contains the passed parameter.
As you can see below I am trying to generate a variable name from “Q” + ActiveQuestionHolder + “Answer” with a value of document.querySelector(QuestionMenu).value;
In console I am coming up with “SyntaxError: unexpected token: string literal”.
I realize there maybe a better way but I am unsure what that maybe.
function QChoiceFunction(ActiveQuestionHolder) {
QuestionMenu = "#Q" + ActiveQuestionHolder +"Choices";
QuestionClassAnswer = ".Q"+ ActiveQuestionHolder +".Answer";
let "Q" + ActiveQuestionHolder + "Answer" = document.querySelector(QuestionMenu).value; // Takes value from selected dropdown ID and assigns to variable -- Getting element content
console.log(QAnswer);
document.querySelector(QuestionClassAnswer).textContent = QAnswer; // Puts the Value into the div with the proper class.
//QuestionResponse = "Q" + ActiveQuestionHolder +"Answer";
//QAnswer = QuestionResponse;
console.log("Q1Answer is = " + Q1Answer);
//console.log("QuestionResponse is = " + QuestionResponse);
}
QChoiceFunction(1);
I am trying to create variables Q1Answer, Q2Answer, Q3Answer etc based on the parameter passed into the function.
So far I am able to create the variable value with = document.querySelector(QuestionMenu).value; which is pulling data from a drop-down menu.
If you really need to create references on the fly, you could define an object to hold them all and then assign your dynamic names to it. For instance:
function QChoiceFunction(ActiveQuestionHolder) {
QuestionMenu = "#Q" + ActiveQuestionHolder +"Choices";
QuestionClassAnswer = ".Q"+ ActiveQuestionHolder +".Answer";
let questions = {};
questions["Q" + ActiveQuestionHolder + "Answer"] = document.querySelector(QuestionMenu).value;
// You can now reference your questions as: questions.Q1Answer or questions["Q1Answer"]
...
}
You cannot create local variables that way as const, let, and var all expect a valid variable name as a word immediately after them. This means that you cannot construct those names right there.
What you can do instead, is define an object inside your function, and instead of creating variables on the fly, you can create object properties on the fly.
The solution is as follows:
function QChoiceFunction(ActiveQuestionHolder) {
// some code...
// define your "dynamic variables" container object
const values = {};
// define the property name using template literals
// or replace the value with: 'Q' + ActiveQuestionHolder + 'Answer'
const propertyName = `Q${ActiveQuestionHolder}Answer`;
// create and assign a new property to the object
values[propertyName] = document.querySelector(QuestionMenu).value;
// you can call, assign and log the new "variable" this way
console.log("Q1Answer is = ", values[propertyName]);
// some code...
}
Keep in mind that this allows you to create as many properties in the object as you want, and in the code above, if your ActiveQuestionHolder parameter contains the value 1, then values[propertyName] is exactly the same as values.Q1Answer.

Concatenate variable with a string to define another variable

I have a variable in a JavaScript
say like this
var divId = 2;
now I want to define some variable which will be like this
var day_2_0 = $("#rules_" + divId + "_offer_number").val();
but I dont want to define var day_2_0 straightforward.
I want something like this, if at all possible
var day = "day_"+divID+"_0";
so that var (var day) => var day_2_0;
Is anything like this possible in JavaScript?
NOTE: its something equivalent to this php snippet
$offer = "offer1";
$$offer then means $offer1
so if we write echo $$offer; then it means echo $offer1;
To my knowledge there are 2 ways you can do it:
1.eval (maybe avoid this one), i.e.
eval('var day_' + variableHere);
2.use an object
var someThing = {};
someThing['day_' + variableHere];
// then get the value by
someThing.day_variableValue;
Google eval for a million opinions on its use

Google javascript - accessing and renaming numeric object names

I imported json data into google scripts with:
var doc = Utilities.jsonParse(txt);
I can access most of the objects like such...
var date = doc.data1.dateTime;
var playerName = doc.data1.playerName;
var playerId = doc.data1.playerID;
var teamNumber = doc.data2.personal.team;
A bunch of objects I need to access have numbers as object names...
doc.data2.personal.team.87397394.otherdata
doc.data2.personal.team.87397395.otherdata
doc.data2.personal.team.87397396.otherdata
doc.data2.personal.team.87397397.otherdata
...but when I try to read the data with...
var teamId = doc.data2.personal.team.87397394;
... I get an error "Missing ; before statement."
I tried this...
var teamId = doc.data2.personal.team[87397394];
... and get "teamId undefined" in the log.
I also tied this with the same result...
var teamId = doc.data2.personal.team[+'6803761'];
I can read in the names as strings very easily with "For In", but can't get to the objects themselves. Every example I've found so far uses the brackets so I'm stumped what to try next.
Thank you!
Brian
UPDATE
I used this per your suggestions to get the object name into a variable and using the variable in brackets. No error but var test remains "undefined"...
for(var propertyName in doc.data2.personal.team) {
// propertyName is what you want
// you can get the value like this: myObject[propertyName]
Logger.log (propertyNames);
var test = doc.data2.personal.team[propertyName];
}
The log shows the object names, as expected...
87397394
87397395
87397396
87397397
I'm thinking it's a bug in Google's implementation. Here is an example if anyone wants to verify it. test will return undefined...
function myFunction1() {
var txt = UrlFetchApp.fetch("http://www.hersheydigital.com/replays/replays_1.json").getContentText();
var doc = Utilities.jsonParse(txt);
for(var propertyName in doc.datablock_battle_result.vehicles) {
Logger.log (propertyName);
var test = doc.datablock_battle_result.vehicles[propertyName];
}
}
The problem seems to be in the Utitlies.jsonParse. The following works fine
var txt = UrlFetchApp.fetch("http://www.hersheydigital.com/replays/replays_1.json").getContentText();
var doc = JSON.parse(txt);
for(var propertyName in doc.datablock_battle_result.vehicles) {
var vehicle = doc.datablock_battle_result.vehicles[propertyName];
Logger.log('Vehicle id is ' + propertyName);
Logger.log('Vehicle value is ' + JSON.stringify(vehicle));
break;
}

Is there a way to make a dynamic variable name based on the value of another variable?

Is there a way to make the value of a variable the name for another variable? For example, I want the variable name (value_of_i) to be what ever number "i" is during that iteration. The while loop below is not what I'm using it for, it's just to explain what I'm asking.
var i = 1;
while(i<10)
{
var value_of_i = "This loop has ran " + i + "times.";
i++;
}
For the first iteration, "i" is equal to 1 so I would want the variable name to be "1":
var 1 = "This loop has ran " + i + "times.";
And the second interation:
var 2 = "This loop has ran " + i + "times.";
Yes. Using bracket notation (Here is a tutorial in MDN)
Here is a working fiddle
When doing something like containingObject[stringVariable] you are accessing the property in containingObject whose name is the value stored in stringVariable.
// this assumes browser JavaScript where window is the global namespace
// in node.js this would be a little different
var i=0;
while(i<10){
window["counters"+i] = "This is loop has ran " + i + "times.";
i++;
}
console.log(counters3);
If you'd like you can use this instead of window, however this might fail in strict mode.
Here is the main explanation of how bracket notation works from the MDN link above:
Properties of JavaScript objects can also be accessed or set using a bracket notation. Objects are sometimes called associative arrays, since each property is associated with a string value that can be used to access it. So, for example, you could access the properties of the myCar object as follows:
myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;
You can also access properties by using a string value that is stored in a variable:
var propertyName = "make";
myCar[propertyName] = "Ford";
propertyName = "model";
myCar[propertyName] = "Mustang";
You can't make a variable name a number, its not a valid name. So var 1="" is invalid.
But to dynamically set the value you can do
var x = "variablenamehere";
window[x] = "variablevaluehere";
Thats the same as
var variablenamehere
except that it will be scoped as a global variable and will be accessible everywhere, rather than being limited to the current function scope.
Why not store your strings in an array that is indexed by i?
That way you can reference them later efficiently and easily;
var loopI = new Array();
for(var i = 0; i < 10; ++i) {
loopI[i] = "This loop has ran " + i + "times.";
}
This works:
var o = {};
var d = "dog";
for (var k = 0; k < 5; k += 1) {
o[d+k] = k*100;
}
console.log(o.dog3); // 300
This comes closer to doing what you want:
var N = {};
var M = {};
var i = 1;
while(i<10)
{
N[i] = "This loop ran " + i + " times.";
// Or, so you can use dot notation later:
M['OO'+i] = "This loop ran " + i + " times.";
// Those are capital O's, not zeros. Numbers won't work.
i++;
}
console.log(N[3]); // This loop ran 3 times.
console.log(M.OO7); // This loop ran 7 times.
The 'OO' notation could cause bewilderment and wasted time for others trying to use your code; but it could also be a source of amusement for them. This reminds me of a chess board after white's first two moves are to bring out a knight and then put it back. The board then seems to show that black moved first, and some people will endlessly insist that the configuration proves there was illegal play unless someone tells them what happened.

Get variable names with JavaScript

I want to create a log function where I can insert variable names like this:
var a = '123',
b = 'abc';
log([a, b]);
And the result should look like this in the console.log
a: 123
b: abc
Get the value of the variable is no problems but how do I get the variable names? The function should be generic so I can't always assume that the scope is window.
so the argument is an array of variables? then no, there is no way to get the original variable name once it is passed that way. in the receiving end, they just look like:
["123","abc"];
and nothing more
you could provide the function the names of the variables and the scope they are in, like:
function log(arr,scope){
for(var i=0;i<arr.length;i++){
console.log(arr[i]+':'scope[arr[i]]);
}
}
however, this runs into the problem if you can give the scope also. there are a lot of issues of what this is in certain areas of code:
for nonstrict functions, this is window
for strict functions, this is undefined
for constructor functions, this is the constructed object
within an object literal, this is the immediate enclosing object
so you can't rely on passing this as a scope. unless you can provide the scope, this is another dead end.
if you pass them as an object, then you can iterate through the object and its "keys" and not the original variable names. however, this is more damage than cure in this case.
I know you want to save some keystrokes. Me too. However, I usually log the variable name and values much like others here have already suggested.
console.log({a:a, b:b});
If you really prefer the format that you already illustrated, then you can do it like this:
function log(o) {
var key;
for (key in o) {
console.log(key + ":", o[key]);
}
}
var a = '1243';
var b = 'qwre';
log({
a:a,
b:b
});
Either way, you'd need to include the variable name in your logging request if you want to see it. Like Gareth said, seeing the variable names from inside the called function is not an option.
Something like this would do what you're looking for:
function log(logDict) {
for (var item in logDict) {
console.log(item + ": " + logDict[item]);
}
}
function logSomeStuff() {
var dict = {};
dict.a = "123";
dict.b = "abc";
log(dict);
}
logSomeStuff();
Don't know if this would really work in JS... but you can use a Object, in which you can store the name and the value:
function MyLogObject(name, value) {
this.name = name;
this.value = value;
}
var log = [];
log.push(new MyLogObject('a', '123'));
log.push(new MyLogObject('b', 'abc'));
for each (var item in log) {
if (item.value != undefined)
alert(item.name + "/" + item.value);
}
Then you can loop thru this Object and you can get the name and the value
You can't access the variable names using an Array. What you could do is use objects or pass the variable names as a String:
var x = 7;
var y = 8;
function logVars(arr){
for(var i = 0; i < arr.length; i++){
alert(arr[i] + " = " + window[arr[i]]);
}
}
logVars(["x","y"]);
I had a somewhat similar problem, but for different reasons.
The best solution I could find was:
MyArray = ["zero","one","two","three","four","five"];
MyArray.name="MyArray";
So if:
x=MyArray.name;
Then:
X=="MyArray"
Like I said, it suited my needs, but not sure HOW this will work for you.
I feel silly that I even needed it, but I did.
test this.
var variableA="valor01"; <br>
var variableB="valor02";
var NamevariableA=eval('("variableA")');<br>
var NamevariableB=eval('("variableB")');<br>
console.log(NamevariableA,NamevariableB);
atte.
Manuel Retamozo Arrué

Categories