Alan
Alan

Reputation: 1287

Exception thrown with Two Dimensional Array in Javascript

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

Answers (1)

Kenney
Kenney

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

Related Questions