Reputation: 1287
I want to have an Object with a two dimensional array in it. it will hold questions with associated choices and the correct answer. The first time thru it works correctly but the second time with i= 1 k= 0 I get an exception. Here is the relevant code with the exception thrown after the first entry in the object:
var testquestions = [{
question:[],
choices:[[]],
answer:[],
}
];
var i = 0;
$( "#opener" ).click(function() {
$( "#dialog" ).dialog( "open" );
$( "#dialog" ).dialog({
minWidth: 700,
minHeight: 650,
buttons: [
{
text: "Add Question",
click: function() {
i = testquestions[0].question.length;
testquestions[0].question[i] = $( "#question" ).val();
for(var k = 0; k < 4; k++){
if ($("#" + k).val() != "") {
alert("i and k values are " + i + "nd " + k);
testquestions[0].choices[i][k] = $( "#" + k ).val();
}
} // for k
testquestions[0].answer[i] = $("#correctAnswer").val();
$("#test")[0].reset();
alert(testquestions[0].question[i]);
}
}
exception
TypeError: testquestions[0].choices[i] is undefined
testquestions[0].choices[i][k] = $( "#" + k ).val();
Can someone tell me if I am declaring and invoking the 2-d array correctly? The exception gets thrown when i = 1. Thanks Update: Answer below did solve my problem.
Upvotes: 0
Views: 133
Reputation: 9093
testquestions[0].choices[i]
is not defined (because of choices:[[]]
) and never assigned, so you can't access it with [k]
. Add a
testquestions[0].choices[i] = [];
right below the
testquestions[0].question[i] = $( "#question" ).val();
to fix that.
Notes:
var foo = { choices:[[]] }
is equivalent to
var foo = {};
foo.choices = [];
foo.choices[0] = [];
It initializes the choices
field to be an array with one element: an empty array. So, .choices[0]
exists, but choices[1]
does not, which causes the error on choices[1][k]
.
Tou might want to use console.log()
(press F12 to see it) instead of alert()
, as that gets annoying inside loops. ;-)
It's best not to use #1
. See the note on this page: have an id
always start with a letter.
Since a question always has some (4) options, perhaps you could use this structure: { question: "?", choices: ["A","B","C"], answer: "C" }
var testquestions = [];
function addQuestion( q, c, a ) {
testquestions.push( { question: q, choices: c, answer: a } );
}
and your handler:
click: function() {
addQuestion(
$( "#question" ).val(),
$( 'input.choice' ).map( function(i,e){ return $(e).val();}).get(),
$("#correctAnswer").val()
);
$("#test")[0].reset();
}
you would need to change the <input id='1'>
... <input id='4'>
to <input class='choice'>
.
update
var testquestions = [{
question:[],
choices:[],
answer:[],
}
];
var i = 0;
$( "#opener" ).click(function() {
i = testquestions[0].question.length;
testquestions[0].question[i] = $( "#question" ).val();
testquestions[0].choices[i] = [];
for(var k = 0; k < 4; k++){
if ($("#c" + k).val() != "") {
testquestions[0].choices[i][k] = $( "#c" + k ).val();
}
} // for k
testquestions[0].answer[i] = $("#correctAnswer").val();
console.log("Added question", testquestions[0] );
$("#test")[0].reset();
}
);
fieldset { display: inline-block; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='dialog'>
<form id='test'>
Q <input id='question'/><br/>
A <input id='correctAnswer'/><br/>
C <fieldset label='foo' title='bar'>
<input id='c0' class='choice'/><br/>
<input id='c1' class='choice'/><br/>
<input id='c2' class='choice'/><br/>
<input id='c3' class='choice'/><br/>
</fieldset>
<button id='opener'>add question</button>
</form>
</div>
Upvotes: 2