4156
4156

Reputation: 400

Cannot ready property of '0' of undefined - Pulling data from an object of arrays

I'm creating a quiz app using Javascript and I've come across an error that is puzzling me so I decided to post it on here and maybe someone sees something different then me.

I have an object of arrays called quizQ --- inside this object is my question and answer list. It is structured like this - I should mention that testbank does get initialized into quizQ in another function in my script file and all the console.logs confirm this, so the problem must lie in the for loop

var testBank = [
    {
        qTitle: "Commonly used data types DO NOT include:",
        picks: ["strings", "booleans", "alerts", "numbers"],
        ans: "alerts"
      },
      {
        qTitle: "The condition in an if / else statement is enclosed within ____.",
        picks: ["quotes", "curly brackets", "parentheses", "square brackets"],
        ans: "parentheses"
      },
      {
        qTitle: "Is JavaScript fun to work with?",
        picks: ["No", "Sometimes", "What is Javascript", "Not just yes, but HELL YES!"],
        ans: "Not just yes, but HELL YES!"
      },
      {
        qTitle: "DOM is an abreviation for ____",
        picks: ["Data Object Mode", "Dumb Old Man", "Document Object Model", "Dutle Opo Mipsy"],
        ans: "Document Object Model"
      },

--- Pretty simple questions I pulled from another app on Github. So what I've done is created a function that will put these picks in a list so I can choose the one I want to answer with. I use the qTitle as the header for each question and after you complete it you are presented with another. ---

The problem is when I run the function and I run the for loop for it, it keeps telling me It cannot read undefined of '0' which is the first index the for runs over. Here is my code

 current = quizQ.pop();
    console.log(current)
    let questionServed = document.createElement('h2');

    questionServed.setAttribute("question", current.qTitle);
    questionServed.textContent = current.qTitle;
    testEl.appendChild(questionServed)

    let choices = document.createElement('ul');

    choices.setAttribute('id', 'choices'); 
    testEl.appendChild(choices)
    
    for (let i = 0; i < current.picks.length; i++) {
        let pickList = document.createElement('li')
        pickList.setAttribute('pick-value', current.pick[i]);
        pickList.setAttribute('id', 'questionNum' + i);
        pickList.textContent = current.pick[i];

        choices.appendChild(pickList)
        
    }

I've console.log(current) and it returns the last array in the testBank as expected, however when the for loop runs, it keeps giving me the error mentioned above. I assume I'm writing the statement incorrectly current.pick[i] but I assumed that it would go into current, then picks, and pull out the pick[0] which would be one of the options given.

Any help would be greatly appreciated!

Upvotes: 0

Views: 51

Answers (2)

cjcurrie
cjcurrie

Reputation: 624

It's likely a typo with current.pick. Ensure all members are named correctly and consider using Typescript for future error checking. https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html

Upvotes: 0

ProfDFrancis
ProfDFrancis

Reputation: 9441

A good plan to avoid this is to have a convention that arrays are named with a plural

In your case the problem is pick versus picks.

for (let i = 0; i < current.picks.length; i++) {
    let pickList = document.createElement('li')
    pickList.setAttribute('pick-value', current.picks[i]);
    pickList.setAttribute('id', 'questionNum' + i);
    pickList.textContent = current.picks[i];

    choices.appendChild(pickList)

It is often difficult to remember whether the array is picks or pick. After all, when you select one element, you think to yourself that you are selecting element #3, so why shouldn't it be called pick[3]?

A convention to avoid this is that the array should be called picks, and an individual value from the array, if you need to extract it as a single item, you can call pick.

Sticking to this convention makes it easier to avoid the problem.

Upvotes: 2

Related Questions