Tosh
Tosh

Reputation: 130

js add event listener not working

I am trying to load interactivly some questins from questions' array (q) into my page and after student clicks at one of the 2 questions register the answer and change the question using js while loop. What is my mistake that it doesn't work?

var q = [
  ['NFR', 'Reusability'],
  ['NFR', 'Robustness'],
  ['FR', 'Reporting Requirements'],
  ['FR', 'Historical Data']
];

var correct = 0;
var incorrect = 0;
var total = q.length;
var i = 0;

document.getElementById('nick').innerText = name;
document.getElementById('question').innerText = q[0][1];

var nfr = document.getElementById('non-functional');
var fr = document.getElementById('functional');

function callback(ans) {
  if (q[i][0] === ans) {
    correct++;
  } else {
    incorrect++;
  };
  if (i < q.length - 1) {
    i++;
    document.getElementById('question').innerText = q[i][1];
  } else {
    location.href = "answer.html";
  }
}

nfr.addEventListener('click', callback('NFR'));
fr.addEventListener('click', callback('FR'));

Upvotes: 0

Views: 54

Answers (2)

jvdh
jvdh

Reputation: 308

Your while loop is looping endlessly, because the only thing it does logically is set toNext to False, set some event listener callbacks and then evaluate toNext again, which will always be False. So i++ will never be called and i < q.length will always be True.

Get rid of the while loop. Write a separate function that evaluates the answer and updates your window with the next question. Use that function as callback for the click events. In a callback function this will be set to the object calling the function, so you could write a function like this:

function callback() {
    if (this.id == q[i][0]) {
        window.correct++;
    } else {
        window.incorrect++;
    }

    i++;

    set_question(i); // Logic to set the i-th question.
}

Edit

function callback(ans) {
    // This function will return 
    // another function with the ans 
    // variable set, which in turn 
    // will be called as a callback 
    // when needed by the 'click' event.
    return function () {
        if (q[i][0] === ans) {
            correct++;
        } else {
            incorrect++;
        };

        if (i < q.length - 1) {
            i++;
            document.getElementById('question').innerText = q[i][1];
        } else {
            location.href = "answer.html";
        }
    }
}

Upvotes: 1

obfish
obfish

Reputation: 667

Event listeners are executed asynchronously and the code you write might assumes that the listeners can block loop execution. To fix this, try removing the loop and move the logic of switching to the next question into the listener callback.

Upvotes: 1

Related Questions