JavaScript - Using a variable to refer to a property name? [duplicate] - javascript

This question already has answers here:
Add a property to a JavaScript object using a variable as the name? [duplicate]
(14 answers)
Closed 8 years ago.
I am creating my own object:
gridObject = new Object();
I am then using jquery to pull the contents of list item tags, which themselves are filled with tags that have specific class names:
<li row="1"><p class="department" rowitem="department">Photography</p>...</li>
I am pulling them using this code:
//make object from results
gridObject = new Object();
//get all the rows
var rowlist = $('li[row]');
for(var r=0; r<rowlist.length; r++) {
//make gridObject row element here
//get the row content
var thisrow = $(rowlist[r]).html();
//get all the p tags
var rowitems = $(thisrow + 'p.[rowitem]');
//get field name
for(var ri=0; ri<rowitems.length; ri++) {
if (r < 2) { //this is temporary just for testing
var fieldname = $(rowitems[ri]).attr('rowitem');
var fieldvalue = $(rowitems[ri]).html();
}
}
Ia m getting hung up passing this into my object. Two questions. Can an object property be made with a variable name, like so
griObject.fieldname = fieldvalue;
and can the objects have parent/child relationships such as:
gridObject.r.fieldname = fieldvalue;
in this case both r and fieldname would be variables. Or should I just be working associative arrays to achieve something similar?
This is in answer to a follow up question I posted below: "Is there a print_r equivalent in javascript" - you can use iterator, a bit more typing but does the trick:
//loop through search data
var it = Iterator(filteritems);
for(var pair in it) {
console.log("key:" + pair[0] + ", value:" + pair[1] + "\n");
}

If you want to use a variable property name, use subscript syntax:
var fieldname = 'test';
//These two lines are equivalent as long as fieldname is 'test':
gridObject[fieldname] = fieldvalue;
gridObject.test = fieldvalue

Related

Why does javascript reads var as a string if i add '+' to it?

I have field names in my firestore document as
videolink1-"some video link"
videolink2-"some video link"
videolink3-"some video link"
I am using a for loop to get all videolinks present in the document.
if (doc.exists) {
for (var i = 1; i == videocount; i++) { //videocount is 3
var data = doc.data();
var videolink = data.videolink+i;
//creating new paragraph
var p = '<p class ="trackvideostyle">'+"Your Video Link : "+String(videolink)+'</p>\';
document.getElementById("btn").insertAdjacentHTML('beforebegin', p);
}
But this for loop is creating var values which are being read as string and firestore is returning me NaN as I dont have these fields :
data.videolink+1
data.videolink+2 //Firestore is returning null as i dont have these document fields
data.videolink+3
How can I write for loop so that var values are created like this and firestore reads it as:
videolink1
videolink2
videolink3
I think you could try something like this,
var videolink = data[`videolink${i}`];
Refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
you are using "data.videolink+i" and javascript does not evaluate the value after the "." instead it is treated as the object's property. you need to use [] for evaluation. try this I hope this will work
if (doc.exists) {
for (var i = 1; i == videocount; i++) {
var data = doc.data();
var videolink = data[videolink+i];
//creating new paragraph
var p = '<p class ="trackvideostyle">'+"Your Video Link :
"+String(videolink)+'</p>\';
document.getElementById("btn").insertAdjacentHTML('beforebegin',
p);
}
Why it doesn't work
The dot operator (property accessor) has higher precendense, so it is evaluated first, so you get the value of the property and then you concatenate the value of your i variable.
What should you do
You can use another property accessor - square brackets, just like in arrays:
data['videolink']
You can build your property name inside of the square brackets:
data['videolink' + i]
or using template literals:
data[`videolink${i}`]
You can do this by using
1. template strings
..
var videolink = `${data.videolink}${i}`
..
2. concat()
..
var videolink = data.videolink.concat(i.toString());
..

Using map\reduce with nested elements in javascript

I have a search form that allows the user to add as many search terms as they like. When the user enters all of the search terms and their search values and clicks search, a text box will be updated with the search terms. I've got this working with a for loop, but I'm trying to improve my dev skills and am looking for a way to do this with map\filter instead.
Here's the code I'm trying to replace:
var searchTerms = $("#search-form").find(".mdc-layout-grid__inner");
var searchString = "";
for(var i = 0; i < searchTerms.length - 1; i ++)
{
var select = $(searchTerms[i]).find(".select2-selection")[0];
var selectText = $(select).select2('data')[0].text + ":";
var textBox = $(searchTerms[i]).find(".mdc-text-field__input")[0];
searchString = searchString += selectText.replace(/\./g,"").replace(/ /g,"") + textBox.value;
if(i < searchTerms.length - 1)
{
searchString = searchString += " ";
}
}
$("#er-search-input").val(searchString);
Here's a codepen of the current solution.
i'm trying the below, but I get the feeling I'm miles away:
const ret = searchTerms.map((u,i) => [
$($(u[i]).find(".select2-selection")[0]).select2('data')[0].text + ":",
$(u[i]).find(".mdc-text-field__input")[0].value,
]);
My question is, is it possible to do this with map?
Firstly you're repeatedly creating a jQuery object, accessing it by index to get an Element object only to then create another jQuery object from that. Instead of doing this, you can use eq() to get a specific element in a jQuery object by its index.
However if you use map() to loop through the jQuery object then you can avoid that entirely by using this to reference the current element in the iteration. From there you can access the required elements. The use of map() also builds the array for you, so all you need to do is join() the results together to build the required string output.
Finally, note that you can combine the regex expressions in the replace() call by using the | operator, and also \s is more robust than using a whitespace character. Try this:
var $searchTerms = $("#search-form").find(".mdc-layout-grid__inner");
var searchString = $searchTerms.map(function() {
var $searchTerm = $(this);
var selectText = $searchTerm.find('.select2-selection').select2('data')[0].text + ':';
var $textBox = $searchTerm.find('.mdc-text-field__input:first');
return selectText.replace(/\.|\s/g, "") + $textBox.val();
}).get().join(' ');
$("#er-search-input").val(searchString);

Google Sites Listitem

I am working with the google sites list item.
The classes are Here and Here
I have been able to iterate through the columns and put all of the column headers in to one array with the following code.
//Global
var page = getPageByUrl(enter URL here)
var name = page.getName();
function getInfo() {
var columns = page.getColumns();
//Get Column Names
for (var j in columns) {
var cName =columns[j].getName();
columnList.push(cName);
}
}
Now I want to be able to get each row of the listitem and put it in its own array.
I can add the variable
function getInfo() {
var columns = page.getColumns();
var listItems = page.getListItems();//new variable
//Get Column Names
for (var j in columns) {
var cName =columns[j].getName();
columnList.push(cName);
}
}
Now that I have the variable the output is [ListItem, ListItem, ListItem, ListItem]
So I can use a .length and get a return of 4.
So now I know I have 4 rows of data so based on my wants I need 4 arrays.
Small interjection here, Not a coder by trade but code as a precursor to wants becoming needs.
A buddy of mine who is a JS coder by trade showed me this code which does work. With the logger added by me.
for (var i in listItems) {
if (listItems.hasOwnProperty(i)) {
item = listItems[i];
for (var x = 0; x < columnList.length; x++) {
attrib = item.getValueByName(columnList[x]);
Logger.log("Logging value of get list page get value by name = " + columnList[x] + " " + attrib);
}
}
}
Which brings the total code to
var name = page.getName();
var listItems = page.getListItems();
var listCount = listItems.length
var listList = [];
var columns = page.getColumns();
var name = columns[0].getName();
var item, attrib = 0;
var columnList = [];
Logger.log(listItems);
Logger.log(name + " was last updated " + page.getLastUpdated());
Logger.log(name + " was last edited " + page.getLastEdited());
var listCount = 0;
//Get Column Names
for (var j in columns) {
var cName =columns[j].getName();
columnList.push(cName);
}
Logger.log(columnList);
// Get index of Due Date
var dueDateValue = columnList.indexOf("Due Date");
Logger.log("The index of due date is " + dueDateValue);
for (var i in listItems) {
if (listItems.hasOwnProperty(i)) {
item = listItems[i];
for (var x = 0; x < columnList.length; x++) {
attrib = item.getValueByName(columnList[x]);
Logger.log("Logging value of get list page get value by name = " + columnList[x] + " " + attrib);
}
}
}
}`
Forgive the above code as it has been a bit of a sketch pad trying to work this out.
I am a bit behind on understanding what is happening here
for (var i in items) { // This is for each item in the items array
if (items.hasOwnProperty(i)) {
if items is an array, how can we use has own property? Doesn't that belong to an object? Does an array become an object?
My questions are two category fold.
Category # 1
What is happening with the hasOwnProperty?
-Does the array become an object and thus can be passed to .hasOwnProperty value
Category # 2
Is this the only way to take the values from the listitem and populate an array
- If it is, is there some way to delimit so I can pass each row into it's own array
- If it isn't , why does it work with the hasOwnProperty and why doesn't it work without it in the example below
for (var i in listItems) {
for (var y = 0; y < columnList.length; y++) {
item = listItems[i];
listList = item.getValueByName(columnList[x]);
Logger.log("Logging my version of list naming " + listList);
}
In which I get a "Invalid argument: name (line 41" response. Highlighting the
listList = item.getValueByName(columnList[x]);
Not looking for a handout but I am looking to understand the hasOwnPropertyValue further.
My current understanding is that hasOwnValue has to do with prototyping ( vague understanding ) which doesn't seem to be the case in this instance
and it has to depend on a object which I described by confusion earlier.
To clarify my want:
I would like to have each row of listitems in its own array so I can compare an index value and sort by date as my current column headers are
["Project", "Start Date" , "End Date"]
Any and all help is much appreciated for this JS beginner of 2 weeks.
An array can be inside of an object as the value of a member:
{"myFirstArray":"[one,two,blue]"}
The above object has one member, a name/value pair, where the value of the member is an array.
Here is a link to a website that explains JSON.
Link To JSON.org
JSON explained by Mozilla
There are websites that will test the validity of an object:
Link to JSONLint.com
An array has elements, and elements in an array can be other arrays. So, there can be arrays inside of arrays.
.hasOwnProperty returns either true or false.
Documentation hasOwnProperty
Interestingly, I can use the hasOwnProperty method in Apps Script on an array, without an error being produced:
function testHasProp() {
var anArrayTest = [];
anArrayTest = ['one', 'two', 'blue'];
Logger.log(anArrayTest);
var whatIsTheResult = anArrayTest.hasOwnProperty('one');
Logger.log(whatIsTheResult);
Logger.log(anArrayTest);
}
The result will always be false. Using the hasOwnProperty method on an array doesn't change the array to an object, and it's an incorrect way of using Javascript which is returning false.
You could put your list values an object instead of an array. An advantage to an object is being able to reference a value by it's property name regardless of where the property is indexed. With an array, you need to know what the index number is to retrieve a specific element.
Here is a post that deals with adding properties to an object in JavaScript:
StackOverflow Link
You can either use dot notation:
objName.newProperty = 'newvalue';
or brackets
objName["newProperty"] = 'newvalue';
To add a new name/value pair (property) to an object.

Loading an array from local storage: result not an array - javascript [duplicate]

This question already has answers here:
How to store objects in HTML5 localStorage/sessionStorage
(24 answers)
Closed 8 years ago.
I have several large multi-dimensional arrays that I'm saving to local storage. They look like this:
[[[-150],[0],[-650],0],[[-100],[0],[-650],0],[[-50],[0],[-650],0] ... ]
The data is '4D' data. When I try loading this 'string' into an array in another JS (in separate html), it doesn't behave like an array- it's only a string.
Here's how I load the data back into the second JS (not sure why the loop didn't work either):
var lay= new Array();
//for(var g=0;g>=9;g++)
//{ lay[g] = localStorage.getItem("key" + g);
// console.log(lay[g]);
//}
lay[0] = localStorage.getItem("key0");
lay[1] = localStorage.getItem("key1");
lay[2] = localStorage.getItem("key2");
//... more here
lay[9] = localStorage.getItem("key3");
After I load this "4D" info into the array, I pull the info out to use it:
var count=0;
var len=0;
for (y=0;y<=1;y++)
{ console.log(lay[y]);
count=1;
len = lay[y].length;
for (x=1;x<=len-1;x++)
{
Rx = lay[y][count][0];
Ry = lay[y][count][1];
Rz = lay[y][count][2];
Rcolor = lay[y][count][3];
When I add this to the code console.log(len); I get the length of characters in the array, not the number of elements. How can I get the data from local storage to come in and behave like array? I thought that the formatting alone would get it behave like an array.
Do I need to parse it back into an array again? If so, I'm guessing I should just output the data in a simpler format to parse it again...
Thanks for the help!
Edit
Here's how I made the local storage:
for (var a=0;a<=14;a++)
{ updateTemp(tStep + a);
$("#temp tbody tr").each(function(i, v){
data[i] = Array();
$(this).children('td').each(function(ii, vv){
data[i][ii] = $(this).text();
rows=ii;
cols=i;
});
});
retval="";
for (var q=0;q<=cols;q++)
{
for (var w=0;w<=rows;w++)
{
var tempv = data[q][w];
var tX = w*50 - 1000;
var tY = 1*50 - 50;
var tZ = q*50 - 1000;
if (tempv==-9){
(dummy=q*w);
}
else {retval += tX +',' + tY + ',' + tZ + ',' + tempv + ',';}
}
}
var kee = "key" + a;
retval = retval.substring(0, retval.length-1); //this is to get rid of the last character which is an extra ,
window.localStorage.setItem(kee, retval);}
JSON encode the array before storing, parse after retrieving.
localStorage.test = JSON.stringify([1,2,3]);
console.log(JSON.parse(localStorage.test));
This is a duplicate of “Storing Objects in HTML5 localStorage”. localstorage only handles strings. As suggested there, serialise your array to a JSON string before storing.

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

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.

Categories

Resources