How to use contents of array as variables without using eval()? - javascript

I have a list of variables or variable names stored in an array. I want to use them in a loop, but I don't want to have to use eval(). How do I do this? If I store the values in an array with quotes, I have to use eval() on the right side of any equation to render the value. If I store just the variable name, I thought I'd be storing the actual variable, but it's not working right.
$(data.xml).find('Question').each(function(){
var answer_1 = $(this).find("Answers_1").text();
var answer_2 = $(this).find("Answers_2").text();
var answer_3 = $(this).find("Answers_3").text();
var answer_4 = $(this).find("Answers_4").text();
var theID = $(this).find("ID").text();
var theBody = $(this).find("Body").text();
var answerArray = new Array();
answerArray = [answer_1,answer_2,answer_3,answer_4,theID,theBody]
for(x=0;x<=5;x++) {
testme = answerArray[x];
alert("looking for = " + answerArray[x] + ", which is " + testme)
}
});

You can put the values themselves in an array:
var answers = [
$(this).find("Answers_1").text(),
$(this).find("Answers_2").text(),
$(this).find("Answers_3").text(),
$(this).find("Answers_4").text()
];
for(x=0;x<=5;x++) {
alert("looking for = " + x + ", which is " + answers[x])
}
EDIT: Or even
var answers = $(this)
.find("Answers_1, Answers_2, Answers_3, Answers_4")
.map(function() { return $(this).text(); })
.get();
If your answers share a common class, you can change the selector to $(this).find('.AnswerClass').
If you need variable names, you can use an associate array:
var thing = {
a: "Hello",
b: "World"
};
var name = 'a';
alert(thing[name]);

This would make it easier to get the array populated.
var answers = new Array();
$("Answers_1, Answers_2, Answers_3, Answers_4", this).text(function(index, currentText) {
answers[index] = currentText;
});

As others have mentioned, if you can put the variables in an array or an object, you will be able to access them more cleanly.
You can, however, access the variables through the window object:
var one = 1;
var two = 2;
var three = 3;
var varName = "one";
alert(window[varName]); // -> equivalent to: alert(one);
Of course, you can assign the varName variable any way like, including while looping through an array.

Related

Using a variable increment to create new variables in Javascript

It might be a beginner's question, but I can't seem to find an answer on this.
The data it is getting is data out of a JSon file. I want it to loop through all the rows it is seeing. The loop works how it is written below and returns me the info I need with the rest of the code. I am trying to create multiple variables like testVar1, testVar2, testVar3, .... I don't know if it is possible to do it this way, or if I need to find another solution.
var i = 0;
for (var x in data) {
var testVar1 = data[0][1]; // works
var testVar[i] = data[0][1]; // doesn't
i += 1;
}
How can I make the testVar[i] work ?
What is the correct syntax for this?
Your code misses the initialization of your array variable: var testVar = [];.
⋅
⋅
⋅
Anyway, you may want to create those variables in the window object :
for (var i = 0; i <= 2; i++) {
name = 'var' + i;
window[name] = "value: " + i;
}
console.log(var0);
console.log(var1);
console.log(var2);
That way you can keep using the "short" variable name.
You can wrap all those variables in an object.
instead of:
var testVar1 = data[0][1];
Try:
var Wrapper = {};
//inside the for loop:
Wrapper["testVar" + i] = data[0][i];
...and so on.
You'd access them as Wrapper.testVar1 or Wrapper["testVar" + 1].
The problem you're having is pretty simple. You try to declare a variable as an array and in the same statement try to assign assign a value to a certain index. The reason this doesn't work is because the array needs to be defined explicitly first.
var testVar[i] = data[0][1];
Should be replaced with:
var testVar = []; // outside the loop
testVar[i] = data[0][1]; // inside the loop
Resulting in:
var i = 0,
testVar = [],
data = [
['foo', 'bar', 'baz'],
['kaas', 'is', 'baas']
];
for (var x in data) {
var testVar1 = data[0][1];
testVar[i] = data[0][1];
i += 1;
}
console.log('testVar1', testVar1);
console.log('testVar', testVar);
console.log('testVar[0]', testVar[0]);
console.log('testVar[1]', testVar[1]);
If i isn't an integer you should use an object instead. This can be seen in the answer of Tilepaper, although I advise against the use variables starting with a capital letter since they suggest a constant or a class.

Assign string variable to array using for loop

I have a list of string variables and I want to assign all of these to an array, but the list is to much, is there any possible for me to using for loop to assign it.
var class_1 = "some description..";
var class_2 = "some description..";
var class_3 = "some description..";
var class_4 = "some description..";
var class_5 = "some description..";
.
.
var class_100 = "some description..";
var classes = [];
for(var i = 0; i < 100; i++){
//loop string variables to array
}
I think it is not possible for me to assign 100 variables manually to the array. Anyone know any technique? Thank you.
[UPDATE] It requires in SystemVerilog syntax, since I not familiar in that language, so I present the idea in Javascript.
There is no way in SystemVerilog to build an array of values from a list of independently named variables without manually assigning each variable to an element of an array.
classes[0] = class_0;
classes[1] = class_1;
classes[2] = class_2;
...
The fact that the identifiers used for variables names have a numerical sequence is of no consequence because you cannot access identifiers except by the exact name.
If you want to automate this, you will need to change the way the string variables are defined. As people have already posted, this should been modeled using an array to begin with, perhaps using an associative array:
string classes[string];
classes["class_1"] = "some description..";
classes["class_2"] = "some description..";
classes["class_3"] = "some description..";
foreach(classes[name])
// do something with classes[name]
Another option is to use a SystemVerilog class object for each variable
class stringvar;
string m_name;
static stringvar list[$];
function new(string name);
m_name = name;
list.push_back(this);
endfunction
endclass
stringvar class_0 = new("some description..");
stringvar class_1 = new("some description..");
stringvar class_2 = new("some description..");
...
foreach(stringvar::list[item])
// do something with item.m_name
Something like this:
var class_1 = "some description..";
var class_2 = "some description..";
var class_3 = "some description..";
var class_4 = "some description..";
var class_5 = "some description..";
var class_100 = "some description..";
var classes = [];
for(var i = 0; i < 100; i++){
classes.push(window['class_'+i])
}
You have 100 variables? You should sort that out first
I think there is some truth to that comment. But to answer your question: Assuming your variables follow the same naming convention that you example above shows, you can assign predefined variables with array values like so:
var a = []
for(var i = 0; i < num_vars; i++){
var key = 'class_' + (i + 1)
if (this[key])
a.push(this[key])
}
You perhaps can use eval. something like this:
for (var i = 0; i < 100; i++) {
var toEval = "classes.push(class_" + i + ")";
eval(toEval);
}

How to retrieve string stored inside a variable?

I have a variable params inside a function someFunction(),
function someFunction() {
var params = ""
params += "type=" + type + "&intro=" + intro + "&val=" + val; // then I add a value on params
console.log(params.val); // now, how can i do this?
}
Any ideas?
Better to write your custom function.
Here what I have tried.
window.onload = function() {
var params = "";
var type = "types";
var intro = "int";
var val = "values";
params += "type=" + type + "&intro=" + intro + "&val=" + val;
var convertToObject = function(strParams) {
var objQueryString = {};
var arrParam = strParams.split('&');
console.log(arrParam)
arrParam.forEach(function(value, key) {
var arrKyValue = value.split('=');
objQueryString[arrKyValue[0]] = arrKyValue[1];
})
return objQueryString;
}
objParams = convertToObject(params);
console.log(objParams.val, objParams["val"])
}
Here is Plunker
When it's a string, it's a string. You could parse it to get values based on known format, but there is no way of referencing something inside of the string.
Therefore, it's better to store params in the object for later use and create a string only when you need it, based on that object.
So, it could be like this:
var params = {
val: val,
type: type,
intro: intro
};
then, params.val will be accessible. When you'll need a string, you'd do var string = "type=" + params.type + "&intro=" + params.intro + "&val=" + params.val;
Your params variable is just a string. What you are trying to do is access it like an object.
A better solution would be:
// Create an object
var params = {};
// Create the properties
params.type = "some type";
params.val = "some value";
params.intro = "some intro";
// Alternatively
var params = {
type: "some type",
val: "some value",
intro: "some intro"
};
// Function that does something with your params
function doSomething(input) {
console.log(input.val);
}
// Function that converts your object to a query string
function toQueryString(input) {
var keyValuePairs = [];
for (var key in input) {
if (input.hasOwnProperty(key)) {
keyValuePairs.push(encodeURI(key) + "=" + encodeURI(input[key]));
}
}
return keyValuePairs.join("&");
}
doSomething(params);
console.log(toQueryString(params));
Outputs
some value
type=some%20type&val=some%20value&intro=some%20intro
As a side note, it is generally a bad idea to use words that can be potentially a keyword in your code or in the future (IE: params). A better name would be one that is informative, such as welcomeMessage, introduction or employee (Based off the 3 values you listed)
var params = "" is not a function, its a statement. A function in JS is created by using function(params) = {} or in ES6 you can use =>. When you use += on a sting you are saying "take whatever string is already in params and add on to it what Im about to tell you." After your statement is evaluated you have a new string. Although strings can be accessed like arrays e.g. x = 'hello' and then x[0] would return 'h' where 0 refers to the character at the index of the string. You are trying to use dot notation which is used for JS object literals e.g. x = {prop1: 200, prop2: 300} then x.prop1 would return 200. Or using the array syntax you would do x[prop1] instead.
Do it this way, check demo - fiddle:
var value = false, temp;
params.split('&').forEach( function(item) {
temp = item.split('=');
if(temp[0] === 'val') {
value = temp[1];
}
})
console.log(value);

Why Is My JavaScript Object Throwing An Undefined Error?

I am getting this error in my console:
Uncaught TypeError: Cannot read property 'kbsrc' of undefined
I get this error because I think there may be something wrong with the way I created my JavaScript Object. I have never created an object that is as multidimensional as this one so I am probably screwing up the syntax somewhere. I generate the objects in the mark-up file here:
var kb_work = {}
kb_work['2014'] = {};
kb_work['2014']['kbid'] = ["51","47"];
kb_work['2014']['kbsrc'] = ["images\/images-4.jpeg","images\/imgres-3.jpeg"];
kb_work['2014']['kbtitle'] = ["shalom","Test 6"];
kb_work['2014']['kbmedium'] = ["2x2","Oil"];
kb_work['2014']['kbsize'] = ["2x2","2x6"];
kb_work['2014']['kbdate'] = ["2014","2014"];
kb_work['2013'] = {};
kb_work['2013']['kbid'] = ["55","54","53","52","50"];
kb_work['2013']['kbsrc'] = ["images\/imgres-4.jpeg","images\/imgres-3.jpeg","images\/imgres-1.jpeg","images\/images.jpeg","images\/images-3.jpeg"];
kb_work['2013']['kbtitle'] = ["totally","heheh","Howdy","tickle","hi"];
kb_work['2013']['kbmedium'] = ["oil","oil","2x2","o","oil"];
kb_work['2013']['kbsize'] = ["2x2","2x2","2x2","2x2","2x1"];
kb_work['2013']['kbdate'] = ["2013","2013","2013","2013","2013"];
kb_work['2012'] = {};
kb_work['2012']['kbid'] = ["49"];
kb_work['2012']['kbsrc'] = ["images\/images-2.jpeg"];
kb_work['2012']['kbtitle'] = ["chicked"];
kb_work['2012']['kbmedium'] = ["oil"];
kb_work['2012']['kbsize'] = ["3x4"];
kb_work['2012']['kbdate'] = ["2012"];
Each of these arrays have only one value right now, but will grow as the user adds work. Following this I link to a file, which contains this function (I commented on the specific line) that the TypeError refers to:
function changeGal(gallery_year) {
$("#gallery-control-bar").fadeOut(t);
$("#gallery-image").fadeOut(t);
$("#info").fadeOut(t);
$("#gallery-viewer").fadeOut(t);
//this is where the script chokes up referring to "currentImg" which is 0 and refers to the first value in the array "['2014']['kbsrc']".
$("#gallery-image").html("<img src='" + kb_work[gallery_year]['kbsrc'][currentImg] + "'>");
$("#gallery-title").html(kb_work[gallery_year]['kbtitle'][currentImg]);
$("#gallery-medium").html(kb_work[gallery_year]['kbmedium'][currentImg]);
$("#gallery-size").html(kb_work[gallery_year]['kbsize'][currentImg]);
$("#gallery-date").html(kb_work[gallery_year]['kbdate'][currentImg]);
$("#gallery-control-bar").delay(t + d).fadeIn(t);
$("#gallery-image").delay(t + d).fadeIn(t);
$("#info").delay(t + d).fadeIn(t);
var userCurrent = currentImg + 1;
var userTotal = kb_work[gallery_year][0].length;
$("#current-post").html(userCurrent);
$("#post-total").html(userTotal);
var galWidth = $("#gallery-image" > "img").width();
$("#gallery").width(galWidth);
}
Any thoughts to why it cannot reference the value?
I think you need
$("#gallery-image").html("<img src='" + kb_work[gallery_year][gallery_year + '.kbsrc'][currentImg] + "'>");
because it looks like gallery_year is a year value like 2013, but the key is a concatenation string value like 2013.kbsrc
There is another problem with your structure because kb_work[year] should be an obeject not an array, again the second level of keys need not have the year again.
So the structure can be updated to
var kb_work = {}
kb_work['2014'] = {};
kb_work['2014']['kbid'] = ["46"];
kb_work['2014']['kbsrc'] = ["images\/screen shot 2014-03-05 at 11.31.04 pm.png"];
kb_work['2014']['kbtitle'] = ["Test 5"];
kb_work['2014']['kbmedium'] = ["Oil"];
kb_work['2014']['kbsize'] = ["2x5"];
kb_work['2014']['kbdate'] = ["2014"];
kb_work['2013'] = {};
kb_work['2013']['kbid'] = ["44"];
kb_work['2013']['kbsrc'] = ["images\/screen shot 2014-03-05 at 11.31.04 pm.png"];
kb_work['2013']['kbtitle'] = ["Test 3"];
kb_work['2013']['kbmedium'] = ["Oil"];
kb_work['2013']['kbsize'] = ["2x1"];
kb_work['2013']['kbdate'] = ["2013"];
kb_work['2012'] = {};
kb_work['2012']['kbid'] = ["45"];
kb_work['2012']['kbsrc'] = ["images\/screen shot 2014-03-05 at 11.31.04 pm.png"];
kb_work['2012']['kbtitle'] = ["Test 4"];
kb_work['2012']['kbmedium'] = ["Oil"];
kb_work['2012']['kbsize'] = ["2x3"];
kb_work['2012']['kbdate'] = ["2012"];
then to access it
kb_work[gallery_year]['kbsrc'][currentImg]
Your nesting shows that you think this works differently to how it actually works...
var kb_work = {}
kb_work['2014'] = new Array();
kb_work['2014.kbid'] = ["46"];
Actually results in an object like this: {"2014":[],"2014.kbid":["46"]}
I believe you want this:
var kb_work = {
'2014': [
{ 'kbid': ["46"] }
]
};
Which results in an object like this: {"2014":[{"kbid":["46"]}]}
Now you can access:
kb_work['2014'][0].kbid[0] // 46
And you can pass in the year as a variable containing the string and the 0s can be a variable containing the index.
You can add multiple lines like this:
var kb_work = {
'2014': [
{ 'kbid': ["46"] },
{ 'kbid': ["62"] },
{ 'kbid': ["90"] }
]
};

How do I declare and use dynamic variables in JavaScript?

Suppose I need to declare a JavaScript variable based on a counter, how do I do so?
var pageNumber = 1;
var "text"+pageNumber;
The above code does not work.
In JavaScript (as i know) there are 2 ways by which you can create dynamic variables:
eval Function
window object
eval:
var pageNumber = 1;
eval("var text" + pageNumber + "=123;");
alert(text1);
window object:
var pageNumber = 1;
window["text" + pageNumber] = 123;
alert(window["text" + pageNumber]);
How would you then access said variable since you don't know its name? :) You're probably better off setting a parameter on an object, e.g.:
var obj = {};
obj['text' + pageNumber] = 1;
if you -really- want to do this:
eval('var text' + pageNumber + '=1');
I don't think you can do it sing JavaScript.I think you can use an array instead of this,
var textArray=new Array();
textArray[pageNumber]="something";
Assuming that the variable is in the global scope, you could do something like this:
var x = 1;
var x1 = "test"
console.log(window["x" + x]); //prints "test"
However, a better question might be why you want such behaviour.
You could also wrap your counter in an object:
var PageNumber = (function() {
var value = 0;
return {
getVal: function(){return value;},
incr: function(val){
value += val || 1;
this['text'+value]=true /*or some value*/;
return this;
}
};
})();
alert(PageNumber.incr().incr().text2); //=>true
alert(PageNumber['text'+PageNumber.getVal()]) /==> true
It can be done using this keyword in JS:
Eg:
var a = [1,2,3];
for(var i = 0; i < a.length; i++) {
this["var" + i] = i + 1;
}
then when you print:
var0 // 1
var1 // 2
var2 // 3
I recently needed something like this.
I have a list of variables like this:
var a = $('<div class="someHtml"></div>'),b = $('<div class="someHtml"></div>'),c = $('<div class="someHtml"></div>');
I needed to call them using another variable that held a string with the name of one of these variables like this:
var c = 'a'; // holds the name of the wanted content, but can also be 'b' or 'c'
$('someSelector').html(eval(c)) // this will just use the content of var c defined above
Just use eval to get the variable data.
I just did
I know a lot of the other answers work great, such as window["whatever"] = "x"; but I will still put my own answer here, just in case it helps.
My method is to use Object.assign:
let dict = {};
dict["test" + "x"] = "hello";
Object.assign(window, dict)
a little improvement over bungdito's answer, use the dynamic variable dynamically
var pageNumber = 1;
eval("var text" + pageNumber + "=123456;");
eval(`alert(text${pageNumber})`);
note: usage of eval is strongly discourgae

Categories

Resources