...

View Full Version : Scope issue in loop within a loop



blogical
12-10-2009, 08:16 PM
Hello... Thanks for reading...

I am getting an undefined error when i try to get a value from this array in the interior loop...




// This is the array I am trying to access
AuditTable [0] = ["Visio Modifed date","Word Modified Date","User Status","User Comment","Last Audit","Audit Status","Audit Comment"]
AuditTable [1] = ["11/23/2009 8:52:18 AM","missing","OK","user comment number 1","1/1/2009","ok","audit comment number 1"]
AuditTable [2] = ["11/24/2009 12:21:19 AM","missing","Out of Date","Changes from 2008 not implemented","1/2/2009","Out of Date","needs update"]
AuditTable [3] = ["11/22/2009 9:24:42 PM","missing","Incomplete","Document doesnt cover all possibilities","1/3/2009","Inadequate","needs update"]



I have hard coded values and had success such as:


data = AuditTable[1][0]

But when I put the vars associated with the loop in I get an undefined error - AuditTable[i] is undefined:


// produces error
data = AuditTable[i][j]
//Works but retrieves wrong data
data = AuditTable[j][i]
//Works but retrieves wrong data
data = AuditTable[1][i]
//Works but retrieves wrong data
data = AuditTable[j][2]


I must be trying to access the array incorrectly or something... I have defined all the vars, and tried many combinations, alerted the values of both vars so I can prove it is not a scope issue... Am I missing something obvious? Thanks much...



var reportArray=new Array();
var reportData, title, subTitle, data;


for(i in parmarray)// loop thru AuditTable array and get values
{
title = '<div style="font-family:verdana; font-size:14px; font-weight:bold; margin:25px 0px 5px 30px">';
title += namearray[i][0];
title += '</div>';
reportArray.push(title);//Take compiled variable value and put it into array

for(j=0; j < AuditTable[0].length; j++)// loop thru AuditTable array and get values
{

subTitle = AuditTable[0][j];//points to first row of AuditTable where the labels are
data = AuditTable[1][0];//points to the current row where actual data is

html = i + j +'<div style="font-family:verdana; font-size:12px; color:#696969; font-weight:bold; margin-left:30px;">';
html += subTitle;
html += '</div><div style="font-family:verdana; font-size:12px; color:#a9a9a9; margin-left:30px; margin-bottom:10px">';
html += data;
html += "</div>";

reportArray.push(html);// put results into array
}
}

gusblake
12-10-2009, 08:22 PM
Where does parmarray get its value from? What is namearray?

In the inner loop you are only iterating through the first element of AuditTable array, not the whole thing.

Can you post the complete script?

Philip M
12-10-2009, 10:02 PM
You are not defining or accessing the (pseudo) two-dimensional array correctly. This is not valid:-
AuditTable [0] = ["Visio Modifed date","Word Modified Date","User Status","User Comment", .......]
Follow this shortened example to declare the array of arrays, and populate them:-


<script type = "text/javascript">

var AuditTable=new Array(3);
for (i=0; i <3; i++) {
AuditTable[i]=new Array(3);
}

AuditTable [0][0] = "Visio Modifed date";
AuditTable [0][1] = "Word Modified Date";
AuditTable [0][2] = "User Status",

AuditTable [1][0] = "11/23/2009 8:52:18 AM";
AuditTable [1][1] = "missing";
AuditTable [1][2] = "OK";

AuditTable [2][0] = "11/24/2009 12:21:19 AM";
AuditTable [2][1] = "Out of Date";
AuditTable [2][2] = "Changes from 2008 not implemented";

for (var i=0; i<= 2; i++) {
for (var j=0; j<= 2; j++) {
data = AuditTable[i][j];
alert (data);
}
}

</script>


"If you are 20 and you are not a socialist, then you have no heart. If you are 40 and you are still a socialist, then you have no brain." - Winston Churchill

blogical
12-11-2009, 02:48 AM
Thanks for the responses...

Philip M:
I do understand that this method is not symantically correct... But the amount of data we are using varies and we need to have the ability to dynamically generate new arrays... It appears that this method forces you to declare how many arrays are inside... We did look at this option, but decided it couldnt work for our purposes...


// Hard coded to "3" no?
var AuditTable=new Array(3);


Also, in HTML I worry about writing valid code so I can be sure it displays correctly... If this method works, what are the draw backs to having it be not valid? Do different browsers javascript engines have looser semantics standards like xhtml has strict and transitional? Thanks!

gusblake:
Sorry, I did post an incorrect version of the internal loop... I have been playing with hardcoded values in the data = AuditTable[1][0] line to try to diagnose the issue... It should have been:


data = AuditTable [i][j];


Is it possible that javascript is seeing the value of 'i' as a string or incorrect type of entity?

parmarray and namearray are both formed the same way as Auditable and are purely used to iterate the correct amount of times to get all data...



parmarray [1] = ["file:\/\/\/c:\\data\\PCC-Production\\visio_htmls\\Report_Debt_Matrix.htm", "Quarterly", "Toby", "Accounting", "Reporting"]
namearray [1] = ["Report Debt Matrix"]
wordarray [1] = ["file:///C:/Data/PCC%20-%20rev120509/word_htmls/Report_Debt_Matrix.htm"]

parmarray [2] = ["file:\/\/\/c:\\data\\PCC-Production\\visio_htmls\\Pooled account-v5.htm", "Weekly", "Investment Acctg. Group", "Accounting", "Cash"]
namearray [2] = ["Pooled Account"]
wordarray [2] = [""]




Here is the entire function and a bit of explanation why it is this way...

Basically I am dynamically adding buttons to the DOM. The "Report" button opens a new window that has to have a list of all the data from AuditTable[]. The catch is, that this entire application lives locally and there is no server or database... The arrays and values are written directly into the javascript file by another program and are thus hardcoded. The only things I put manually into this file are the instantiations for each array and var...

Lastly, I am using window.name to pass all this data after it is looped, formatted, pushed, and joined... Is there a better way to get the data into this new window? Regardless, it is all working just fine besides this single var...



// ==================================================================================================== ====
//
// - Adds "Create Report", "Edit Data", "Reset" buttons to Search Bar
// - Called by the createMenus() function on initial page load
//
// ==================================================================================================== ====

function createButtons(div)
{
// Get data for Report Page
var reportArray=new Array();// Holds compiled data to be passed thru window.name to get it to new window
var reportData, title, subTitle, data;

for(i in parmarray)// loop thru AuditTable array and get values
{
title = '<div style="font-family:verdana; font-size:14px; font-weight:bold; margin:25px 0px 5px 30px">';
title += namearray[i][0];
title += '</div>';
reportArray.push(title);//Take compiled variable value and put it into array

for(j=0; j < AuditTable[0].length; j++)// loop thru AuditTable array and get values
{

subTitle = AuditTable[0][j];//points to first row of AuditTable where the labels are
data = AuditTable[i][j];//points to the current row where actual data is

html = '<div style="font-family:verdana; font-size:12px; color:#696969; font-weight:bold; margin-left:30px;">';
html += subTitle;
html += '</div><div style="font-family:verdana; font-size:12px; color:#a9a9a9; margin-left:30px; margin-bottom:10px">';
html += data;
html += "</div>";

reportArray.push(html);// put results into array
}
}
reportData = reportArray.join('');//turn array into a string without commas


// Create "Create Report" button
var reportData;
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Create Report');
//btn.setAttribute('class', 'openGB'); USE THIS FOR GREYBOX
btn.setAttribute('id', 'reportBtn');
btn.setAttribute("onclick", "window.open(\'report.html\',\'"+reportData+"\',\'width=600,height=600,screenX=300,screenY=100,menubar=yes, scrollbars=yes\')");
current= document.getElementById(div);
current.appendChild(btn);

// Create "Edit Data" button
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Edit Data');
//btn.setAttribute('class', 'openGB'); USE THIS FOR GREYBOX
btn.setAttribute('id', 'editDataBtn');
btn.setAttribute('onclick', 'window.location=excelfile');
current= document.getElementById(div);
current.appendChild(btn);

// Create "Reset" button
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Reset');
//btn.setAttribute('class', 'openGB'); USE THIS FOR GREYBOX
btn.setAttribute('id', 'resetBtn');
btn.setAttribute('onclick', 'location.reload()');
current= document.getElementById(div);
current.appendChild(btn);

}



Thank you again for your time and help...

Old Pedant
12-11-2009, 03:35 AM
Did you ever check to see what the values of i and j are at the point where you get the error????

Perhaps i goes out of range for the AuditTable array?

And your use of j, even, makes me nervous.


for(j=0; j < AuditTable[0].length; j++)// loop thru AuditTable array and get values
{
subTitle = AuditTable[0][j]; // this one should always be okay
data = AuditTable[i][j]; // but what if row i the table is *SHORTER* than row zero?????
}


It would be trivial to put checks in there:


if ( isNaN(parseInt(i)) ) alert("i is not an integer");
if ( AuditTable.length == null ) alert("AuditTable is not an array!");
for(j=0; j < AuditTable[0].length; j++)
{
subTitle = AuditTable[0][j];
if ( i >= AuditTable.length ) alert("AuditTable does not have " + i + " rows");
if ( AuditTable[i].length == null ) alert("Row " + i + " of AuditTable is not an array");
if ( j >= AuditTable[i].length ) alert("Row " + i + " does not have " + j + " columns");
data = AuditTable[i][j];
}


Hmmm???

blogical
12-11-2009, 04:14 AM
Thanks for the reply Old Pedant.

Yes, I have output the values of i and j, and they are as expected...
i iterates once for every 7 times of j... It is just the value is not being read properly for some reason when it is inside the []... j works fine right above it and I can output i if I put it in the html var and watch it iterate... AuditTable has values starting from [0][0] to [8][7], but i never get there since the error is thrown... If I hard code any value in place of i, everything works fine...

Thanks again for the help...

blogical
12-11-2009, 09:11 PM
Thank you all for your help...

The issue was due to a mismatch of variable range...

I was thinking that the for,in loop was iterating through until it got to the end and would then just say 'undefined' not that it would throw an error... Such as:



//firstArray has 5 rows
//otherArray has 3
// Throws otherArray[i] is undefined error


for(i in firstArray)
{
data = otherArray[i]
//
}

Well, basically firstArray was a different length than otherArray so, as the veterans stated, it was out of range... I misunderstood the value of firstArray in the for loop condition, and had incomplete data... I figured it out by replacing the for,in loop with just a for loop and adjusting the range until I got it to work, revealing the range issue...



// this one worked because it stayed within range
for(i=0; i<3; i++)
{
data = otherArray[i]
}


Thank you all again for your help.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum