Javascript code saving data to 2d array throws undefined - javascript

I'm writing a script that takes values from a html table, indexes them in aray and then assign every value to a tag in a form.Codepen https://codepen.io/anon/pen/eVLKyB
My problem is that after taking all specified values from array I get
Code responsible for indexing values from table look like this:
function size_index(){
var table = document.getElementsByClassName("product_table_cus");
var index= [[],[]];
var i_index = 0;
var iter = 0; //index of first dim of array
var len = table[0].rows.length;
console.log("Len:"+len);
while(i_index<len) {
//iterate trough rows
console.log("second for, iter:"+ i_index);
var col_inner = table[0].rows[i_index].cells[0].innerHTML; //size param
var col_param = table[0].rows[i_index].cells[1].innerHTML;//size value
var col_size = col_inner.substr(col_inner.indexOf(' ')+1);
console.log("Rozmiar:"+ col_size+" Wartość:"+col_param);
// index[1][0].push("col_size");
// index[i_index][1].push(col_param);
if(col_inner.search("Rozmiar")!==-1)
{
console.log("Inner wtf:"+col_inner+"Ite:"+iter);
index[iter].push(col_inner,col_param);
console.log("Index+:"+index[iter]);
console.log("Ind:"+col_inner+"Val:"+col_param);
}
else if(col_inner.search("Rozmiar")==-1){
}
iter++;
// col_param=0;
// col_size=0;
//iterate through columns
//columns would be accessed using the "col" variable assigned in the for loop
//rows would be accessed using the "row" variable assigned in the for loop
i_index++;
}
return index;
}

You can see it in the console log:
This line of code
console.log("Inner wtf:"+col_inner+"Ite:"+iter);
Produces this output
Inner wtf:Rozmiar XXLIte:2
Your index variable has exactly two values in it.
So of course, if iter is a value greater than one, this line will cause an error:
index[iter].push(col_inner,col_param);
There are two elements in index, so index[2] will return undefined.
Your underlying problem is that [[][]] is not a two dimensional array. It is an array containing two arrays.
A safer way to do this is:
var index= [];
Then, to add an element:
index[iter] = index[iter] || [];
index[iter].push(...);

Related

Pushing values from one array into a Multi-Dimensional Array and got an Error

function studentClasses() {
var names = [];
var course = [];
var sortCourse = [];
var uniqueCourse = [];
var nameCourse = [];
while (records.readNextRecord()) {
var studentNames = records.getStudentName();
var studentCourse = records.getStudentCourseNumber();
names.push(studentNames);
course.push(studentCourse);
sortCourse.push(studentCourse);
sortCourse.sort();
}
// sort a list of courses to find the unique courses
for (var i = 0; i < sortCourse.length; i++) {
if (sortCourse[i] !== sortCourse[i - 1]) {
uniqueCourse.push(sortCourse[i]);
}
}
uniqueCourse.sort;
nameCourse.length = uniqueCourse.length;
// create multi-d array containing names for a certain course
for (var x = 0; x < uniqueCourse.length; x++) {
for (var y = 0; y < course.length; y++) {
if (uniqueCourse[x] === course[y]) {
nameCourse[x].push(names[y]);
}
}
}
}
This is my code that I am working on and I am getting an error of
Uncaught TypeError: Cannot read property 'push' of undefined(…)
I have two arrays ("course" & "names") that contain information that have data in specific indexes. I am trying to compare information from my "uniqueCourse" array to my "course" array and if they match, the index place from "course" would then be used to call the information from the index place in "names".
Here is where the problem is:
When I try to push "names[y]" into a multidimensional array that would have a length equal to uniqueCourse (which is 5 if the code is ran), I get the error.
Question:
Why am I getting an undefined error when I try to use the code
nameCourse[x].push(names[y]);
to push the information from names to nameCourse with x being the corresponding level that I want those names to be stored?
I want:
nameCourse = [ [however many names called from names[y]],
[however many names called from names[y]],
[however many names called from names[y]],
[however many names called from names[y]],
[however many names called from names[y]] ]
Your nameCourse array is filled with undefined
You need to initialize nameCourse[x] to be an array and only then push into it.
Something like below:
nameCourse = new Array(uniqueCourse.length).fill(0);

How to iterate through javascript object and run a function on each value

I am new to JS.
I set up a Saved Search in NetSuite that gives us the image fields (containing URLs) of our items. I am now setting up a script in NS which tests these fields to see what item fields return 404 (i.e. need to be fixed).
My question is, how to set up function imageURLValidator to iterate through the field values of function searchItems?
Below is my start to the process but obviously has much incorrect syntax.
function imageURLValidator() {
var searchResults = searchItems('inventoryitem','customsearch529');
var url = '';
var item = '';
var field = '';
//insert loop here to iterate over items in searchResults array
//loop through items
for (var i = 0, i > searchResults[inventoryObject].length, i++) {
item = searchResults.[inventoryObject].[i];
//loop through fields in item
for (var f = 2, f > item.length, f++) {
field = item[f];
//check URL via item field's value
var code = checkURL(item[field].getvalue([field]));
//generate error based on code variable
createErrorRecord(code,item,field)
}
}
}
function searchItems(type, searchid) {
//defining some useful variables that we will use later
var inventoryArray = [];
var count = 0;
//loading the saved search, replace the id with the id of the search you would like to use
var inventoryItemSearch = nlapiLoadSearch(type, searchid);
//run the search
var inventoryItemResults = inventoryItemSearch.runSearch();
//returns a js array of the various columns specified in the saved search
var columns = inventoryItemResults.getColumns();
//use a do...while loop to iterate through all of the search results and read what we need into one single js object
do {
//remember the first time through the loop count starts at 0
var results = inventoryItemResults.getResults(count, count + 1000.0);
//we will now increment the count variable by the number of results, it is now no longer 0 but (assuming there are more than 1000 total results) will be 1000
count = count + results.length;
//now for each item row that we are on we will loop through the columns and copy them to the inventoryObject js object
for (var i=0; i<results.length; i++){
var inventoryObject = {};
for (var j=0; j<columns.length; j++){
inventoryObject[columns[j].getLabel()] = results[i].getValue(columns[j]);
}
//then we add the inventoryObject to the overall list of inventory items, called inventoryArray
inventoryArray.push(inventoryObject);
}
//we do all of this so long as the while condition is true. Here we are assuming that if the [number of results]/1000 has no remainder then there are no more results
} while (results.length != 0 && count != 0 && count % 1000 == 0);
return inventoryArray;
}
function checkURL(url) {
var response = nlapiRequestURL(url);
var code = response.getCode();
return code;
}
function createErrorRecord(code,item,field) {
if (code == 404){
//create error record
var errorRecord = nlapiCreateRecord('customrecord_item_url_error');
errorRecord.setFieldValue('custrecord_url_error_item', item);
errorRecord.setFieldValue('custrecord_url_error_image_field', field);
}
}
Here I can see searchResults variable will be empty while looping. As your call to searchItems function is async. Which will take some time to execute because I guess it will fetch data from API. By the time it returns value, your loop also would have bee executed. You can test this by putting an alert(searchResults.length) or console.log(searchResults.length). For that you need to use callback function
Also even if you get the results in searchResults. The loop you are doing is wrong. The array you will get is like [{},{},{}] i.e. array of objects.
To access you'll need
for (var i = 0, i > searchResults.length, i++) {
var inventoryObject = searchResults[i] // your inventoryObject
for(var key in inventoryObject){
item = inventoryObject[key]; // here you will get each item from inventoryObject
//loop through fields in item
for (var f = 2, f > item.length, f++) {
field = item[f];
//check URL via item field's value
var code = checkURL(item[field].getvalue([field]));
//generate error based on code variable
createErrorRecord(code,item,field)
}
}
}
And yes welcome to Javascript

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.

Adding for loop results to an array and displaying sum of added elements after the last loop

I have to get some records based on weekly basis for the last weeks, and have to add values from records of one week to an array. So, I declared 6 arrays to store 6 weeks records. My code is:
var w_0 = [];var w_1 = [];var w_2 = [];var w_3 = [];var w_4 = [];var w_5 = [];
var myTotal = 0;
var arr_name = "";
for(var j=0;j<=5;j++)
{
var start_date="";
var end_date="";
//code to fetch the records added between start_date,end_date
//there may be more that one record
var count = getRecordCount(); //My function
//following loop is to fetch value from a record
for(var i=0;i<count;i++)
{
var val1 = getRecordByIndex(i).getValue("rem_val"); //getRecordByIndex() and getValue() are our pre-defined functions.
//here I want to push the values into the array w_0
arr_name = "w_"+j;
[arr_name].push(val1); //this is not working
alert([arr_name]); //showing 'w_0'
}
//and here I want to sum all the array elements when i reaches its maximum
for(var a=0;a<[arr_name].length; a++){
myTotal += parseInt([arr_name][a]);
}
alert("Total value of week"+j+"="+parseInt(myTotal));
}
How can I add values of inner loop to the array based on outer loop?
Any time you find yourself creating variables with sequentially numbered names, you should probably be using an array instead.
var w = [[], [], [], [], []];
Then, wherever you tried to use [arr_name] to refer to a particular w_j variable, you should use w[j].
for(var j=0;j<=w.length;j++)
{
var cur_w = w[j];
var start_date="";
var end_date="";
//code to fetch the records added between start_date,end_date
//there may be more that one record
var count = getRecordCount(); //My function
//following loop is to fetch value from a record
for(var i=0;i<count;i++)
{
var val1 = getRecordByIndex(i).getValue("rem_val"); //getRecordByIndex() and getValue() are our pre-defined functions.
cur_w.push(val1);
alert(cur_w);
}
//and here I want to sum all the array elements when i reaches its maximum
for(var a=0;a<cur_w.length; a++){
myTotal += parseInt(cur_w[a]);
}
alert("Total value of week"+j+"="+parseInt(myTotal));
}
If you want to dynamically manipulate global variables you can use window prefix:
arr_name = "w_"+j;
window[arr_name].push(val1); // This should work

Dynamically create a two dimensional Javascript Array

Can someone show me the javascript I need to use to dynamically create a two dimensional Javascript Array like below?
desired array contents:
[["test1","test2","test3","test4","test5"],["test6","test7","test8","test9","test10"]]
current invalid output from alert(outterArray):
"test6","test7","test8","test9","test10","test6","test7","test8","test9","test10"
JavaScript code:
var outterArray = new Array();
var innerArray = new Array();
var outterCount=0;
$something.each(function () {
var innerCount = 0;//should reset the inner array and overwrite previous values?
$something.somethingElse.each(function () {
innerArray[innerCount] = $(this).text();
innerCount++;
}
outterArray[outterCount] = innerArray;
outterCount++;
}
alert(outterArray);
This is pretty cut and dry, just set up a nested loop:
var count = 1;
var twoDimensionalArray =[];
for (var i=0;i<2;i++)
{
var data = [];
for (var j=0;j<5;j++)
{
data.push("Test" + count);
count++;
}
twoDimensionalArray.push(data);
}
It sounds like you want to map the array of text for each $something element into an outer jagged array. If so then try the following
var outterArray = [];
$something.each(function () {
var innerArray = [];
$(this).somethingElse.each(function () {
innerArray.push($(this).text());
});
outterArray.push(innerArray);
});
alert(outterArray);
A more flexible approach is to use raw objects, they are used in a similar way than dictionaries. Dynamically expendables and with more options to define the index (as string).
Here you have an example:
var myArray = {};
myArray[12]="banana";
myArray["superman"]=123;
myArray[13]={}; //here another dimension is created
myArray[13][55]="This is the second dimension";
You don't need to keep track of array lengths yourself; the runtime maintains the ".length" property for you. On top of that, there's the .push() method to add an element to the end of an array.
// ...
innerArray.push($(this).text());
// ...
outerArray.push(innerArray);
To make a new array, just use []:
innerArray = []; // new array for this row
Also "outer" has only one "t" :-)
[SEE IT IN ACTION ON JSFIDDLE] If that $something variable is a jQuery search, you can use .map() function like this:
var outterArray = [];
var outterArray = $('.something').map(function() {
// find .somethingElse inside current element
return [$(this).find('.somethingElse').map(function() {
return $(this).text();
}).get()]; // return an array of texts ['text1', 'text2','text3']
}).get(); // use .get() to get values only, as .map() normally returns jQuery wrapped array
// notice that this alert text1,text2,text3,text4,text5,text6
alert(outterArray);​
// even when the array is two dimensional as you can do this:
alert(outterArray[0]);
alert(outterArray[1]);
HTML:
<div class="something">
<span class="somethingElse">test1</span>
<span class="somethingElse">test2</span>
<span class="somethingElse">test3</span>
</div>
<div class="something">
<span class="somethingElse">test4</span>
<span class="somethingElse">test5</span>
<span class="somethingElse">test6</span>
</div>
Here you can see it working in a jsFiddle with your expected result: http://jsfiddle.net/gPKKG/2/
I had a similar issue recently while working on a Google Spreadsheet and came up with an answer similar to BrianV's:
// 1st nest to handle number of columns I'm formatting, 2nd nest to build 2d array
for (var i = 1; i <= 2; i++) {
tmpRange = sheet.getRange(Row + 1, Col + i, numCells2Format); // pass/fail cells
var d2Arr = [];
for (var j = 0; j < numCells2Format; j++) {
// 1st column of cells I'm formatting
if ( 1 == i) {
d2Arr[j] = ["center"];
// 2nd column of cells I'm formatting
} else if ( 2 == i ) {
d2Arr[j] = ["left"];
}
}
tmpRange.setHorizontalAlignments( d2Arr );
}
So, basically, I had to make the assignment d2Arr[index]=["some string"] in order to build the multidimensional array I was looking for. Since the number of cells I wanted to format can change from sheet to sheet, I wanted it generalized. The case I was working out required a 15-dimension array. Assigning a 1-D array to elements in a 1-D array ended up making the 15-D array I needed.
you can use Array.apply
Array.apply(0, Array(ARRAY_SIZE)).map((row, rowIndex) => {
return Array.apply(0, Array(ARRAY_SIZE)).map((column, columnIndex) => {
return null;
});
});`

Categories

Resources