0

I am trying to make a simple multiple choice-like quiz using data from an array, but I am getting an error: TypeError: Cannot read property '0' of undefined.

The possible choices should be 4, with the correct answer being the first choice. I have tried searching online for solutions, but I do not know what is causing the error and how to fix it:

var masterlist = [
  ["Indonesia", "Jakarta"],
  ["Malaysia", "Kuala Lumpur"],
  ["Philippines", "Manila"],
  ["Singapore", "Singapore"],
  ["Thailand", "Bangkok"],
  ["Vietnam", "Hanoi"]
];

function randomNoRepeats(array) {
  var copy = array.slice(0);
  return function() {
    if (copy.length < 1) {
      copy = array.slice(0);
    }
    var index = Math.floor(Math.random() * copy.length);
    var item = copy[index];
    copy.splice(index, 1);
    return item;
  };
}
var chooser = randomNoRepeats(masterlist); //randomize choices
//console.log(chooser());

var quizArea = document.getElementById("test-area");

var a = []; // new empty array to store randomized items
var c = []; // new empty array to store randomized items (copy)
var b;
var correctAnswer;

for (var i = 0; i < masterlist.length; i++) {
  b = chooser();
  a.push(b);
}
c = a;
//console.log("a", a, a.length); // ERROR here; expected an array length of 6

for (var i = 0; i < masterlist.length; i++) {
  correctAnswer = c[i];

  var index = a.indexOf(correctAnswer); // remove correct answer from list of other/wrong choices
  a.splice(index, 1);

  var otherChoices = a.slice(0, 3); // choose only 3 wrong/other choices

  var question = document.createElement("p");
  question.innerHTML = "What is the capital of " + correctAnswer[0] + "?"; // ERROR

  var answers = document.createElement("p");
  answers.innerHTML = correctAnswer[1] + ", " + otherChoices[0][1] + ", " + otherChoices[1][1] + ", " + otherChoices[2][1]; // place correct answer at index 0; TypeError: Cannot read property '0' of undefined

  quizArea.appendChild(question);
  quizArea.appendChild(answers);

}
<div id="test-area"></div>

1 Answer 1

1

The issue comes from the statement c = a;. It does not copy the array. Both c and a reference the same array object.

This means that the line a.splice(index, 1) changes a AND c in place.


One solution here is to use a real copy of a in your last for loop.

for (var i = 0; i < masterlist.length; i++) {
  c = a.slice(0); // or c = [...a];
  
  // use `c` here
}

var masterlist = [
  ["Indonesia", "Jakarta"],
  ["Malaysia", "Kuala Lumpur"],
  ["Philippines", "Manila"],
  ["Singapore", "Singapore"],
  ["Thailand", "Bangkok"],
  ["Vietnam", "Hanoi"]
];

function randomNoRepeats(array) {
  var copy = array.slice(0);
  return function() {
    if (copy.length < 1) {
      copy = array.slice(0);
    }
    var index = Math.floor(Math.random() * copy.length);
    var item = copy[index];
    copy.splice(index, 1);
    return item;
  };
}
var chooser = randomNoRepeats(masterlist); //randomize choices
//console.log(chooser());

var quizArea = document.getElementById("test-area");

var a = []; // new empty array to store randomized items
var c;
var b;
var correctAnswer;

for (var i = 0; i < masterlist.length; i++) {
  b = chooser();
  a.push(b);
}
//console.log("a", a, a.length); // ERROR here; expected an array length of 6

for (var i = 0; i < masterlist.length; i++) {
  c = a.slice(0);

  correctAnswer = c[i];

  var index = c.indexOf(correctAnswer); // remove correct answer from list of other/wrong choices
  c.splice(index, 1);

  var otherChoices = c.slice(0, 3); // choose only 3 wrong/other choices
  
  var question = document.createElement("p");
  question.innerHTML = "What is the capital of " + correctAnswer[0] + "?"; // ERROR

  var answers = document.createElement("p");
  answers.innerHTML = correctAnswer[1] + ", " + otherChoices[0][1] + ", " + otherChoices[1][1] + ", " + otherChoices[2][1]; // place correct answer at index 0; TypeError: Cannot read property '0' of undefined

  quizArea.appendChild(question);
  quizArea.appendChild(answers);

}
<div id="test-area"></div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.