2

I'm trying to create variabels on the fly in a for loop. error. What I'm trying to do is: get the values of 32 text fields and trying to store those values into a variable.

for (i = 1; i<=32;i++){
   q[i] = document.getElementById('qty[i]').value;
}

But this yeilds:

Error: 'q' is undefined

Mahmoud Gamal
  • 72,639
  • 16
  • 129
  • 156
like-a-trainee
  • 401
  • 3
  • 8
  • 21
  • always be careful of doing document.getElementById().value directly. If that id doesnt exist, then the object returned is usually null, and you cant take value of null. This will also break your script. – Thomas Jones Apr 26 '12 at 00:36

2 Answers2

3
var q = [];

for (var i = 0; i < 32; i++){
    q[i] = document.getElementById('qty[i]').value;
}

q will contain all of your values. You should declare the array q outside of your for loop, as that's the commonly accepted best practice. If you don't declare q at all, it will be come an implied global variable, something that you probably want to avoid. If you declare q inside your loop, it will get overridden each iteration, so you need to make sure you declare it outside.

Also, you'll note that I changed your for loop from this:

for(i = 1; i <= 32; i++) {

To this:

for (var i = 0; i < 32; i++){

You're looping from 1 to 32; this is incorrect, as arrays in Javascript are 0-indexed; in other words, they start counting from zero. Since this is the case, your for loops also need to start counting at zero, and end at 31. Also, you'll want to declare the var i in your for loop; otherwise, it will become a global variable.


Now, if you really really didn't want to declare q outside of your for loop, you could do what Kirian demonstrated; that is, use an if statement to determine if q has already been declared, and if not, declare it. That would look like this:

for (var i = 0; i < 32; i++){
    if(!q) q = [];
    q[i] = document.getElementById('qty[i]').value;
}

And another note, if qty is an array in your code then you probably want this instead:

var q = [];

for (var i = 0; i < 32; i++){
    q[i] = document.getElementById(qty[i]).value;
}

If instead qty is part of a set of IDs that look like qty[1], qty[2], qty[3]..., then you want this:

var q = [];

for (var i = 0; i < 32; i++){
    q[i] = document.getElementById('qty[' + i + ']').value;
}
Elliot Bonneville
  • 46,945
  • 19
  • 86
  • 120
  • 3
    This is completely false. JavaScript does not have block scope. JavaScript has only function scope and global scope. Declaring a variable within a for loop is completely valid and the variable will be available outside that loop just fine. It is bad practice and confusing though. – Thomas Jones Apr 26 '12 at 00:26
  • Yep. It's confusing as hell to programmers trained in higher level languages, but true, – Thomas Jones Apr 26 '12 at 00:28
  • This still probably won't work unless there is literally an element with `id="qty[i]"`. But it's not entirely clear from the OP what that *is* supposed to be. – Chuck Apr 26 '12 at 00:31
  • @Chuck good catch. OP is not clear on that, but something like `document.getElementById('qty[' + i + ']')` will do the trick. – Thomas Jones Apr 26 '12 at 00:32
  • 1
    "JavaScript has only function scope and global scope." Not true in ES6 (let statement). – Marek Marczak Apr 06 '18 at 17:52
1

Have you tried:

var q = [];
for (var i = 0; i < 32; i++){
  q.push(document.getElementById('qty[i]').value);
}

The syntax q.push(x) appends x to the end of an array.

Jason S
  • 171,795
  • 155
  • 551
  • 900
  • Just out of curiosity, why are you using `q.push`? `q[i]` works just fine. – Elliot Bonneville Apr 26 '12 at 00:31
  • q[i] in this scenario will work fine, but be careful with just doing indexes. They will get you arrays of odd sizes, as javascript will initialize the array up to the index you specified, with each element being undefined. http://jsfiddle.net/uNwSA/ `q.push` is a better practice, and object oriented, unless the indexes are important. – Thomas Jones Apr 26 '12 at 00:35
  • I'm aware of that. I was just wondering why he's using push() in this case as q[i] will work fine and is probably faster. – Elliot Bonneville Apr 26 '12 at 00:41
  • @Kirean While I agree on the use of `push`, what you said is not entirely accurate. `length` is just a special property that is equal to the highest index plus 1. Arrays in JavaScript are sparsely populated, so those other indices are just undefined, not initialized. – Dennis Apr 26 '12 at 00:47
  • @ElliotBonneville [JSPerf](http://jsperf.com/array-push-and-append-by-index) doesn't seem to show any significant speed difference. – Dennis Apr 26 '12 at 00:50
  • @Dennis I stand corrected. http://jsfiddle.net/uNwSA/2/ using the snippet found at http://stackoverflow.com/a/6367736/1093982 I modified the original jsfiddle. It seems that at index 9000, or at index 1, its roughly the same size. I still believe that the memory is being allocated, but since each pointer (for lack of a better word) is referencing "undefined", its negligible memory. – Thomas Jones Apr 26 '12 at 01:09
  • 1
    It's because of the size of the key - 9000 is four characters, 8 is 1 character. `(4-1)*2` accounts for the size byte difference in the calculation. – Dennis Apr 26 '12 at 10:25