I built a Quiz app I have a problem that sometimes the method of correct answer and incorrect answer are run together. The problem occurs occasionally.
I will note that the code works fine. Just the problem I mentioned above that sometimes the methods this._incorrect () and this._correct () Run together at the same time.
'use strict';
/** Import */
import harryPotterName from './NamesArray.js';
/**Const */
const btnAll = document.querySelectorAll('.btn');
const divPicture = document.querySelector('.divPicture');
const scoreDOM = document.querySelector('.score');
class QuizzGame {
/*settings */
#randomNumArr = [
[0, 1, 2, 3],
[4, 5, 6, 7],
[9, 10, 11, 8],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
];
#score = 5;
constructor() {
this.arr = this.#randomNumArr[this._rand()]; // array Destructuring
this.randInArr = Math.floor(Math.random() * 4); // rand in arr [0,2,3,4] = rand [2]
this.id = this.arr.at(this.randInArr); // Slice
btnAll.forEach((btn, i) => {
btn.setAttribute('data-id', this.arr[i]); // Set Attribute [data-id, i]
btn.innerHTML = harryPotterName[this.arr[i]];
btn.addEventListener('click', e => this._ButtonHandler(e));
});
this._init();
}
_rand() {
return Math.floor(Math.random() * this.#randomNumArr.length);
}
_randInArr() {
this.arr = this.#randomNumArr[this._rand()];
this.randInArr = Math.floor(Math.random() * 4); // rand in arr [0,2,3,4] = rand [2]
this.id = this.arr.at(this.randInArr); // Slice
}
_ButtonHandler(e) {
console.log( e.target.dataset.id, this.id);
if ( e.target.dataset.id !== this.id || this.#score <= 0) this._incorrect(); // incorrect Answer
if ( e.target.dataset.id === this.id && this.#score > 0) this._correct(); // correct Answer
}
_incorrect() {
console.log('_incorrect');
scoreDOM.textContent = this.#score <= 0 ? 'you lose' : --this.#score;
this._randInArr();
this._nextQuestion(); // next to the Question
this._showImg(); // render img
}
_correct() {
console.log('_correct');
scoreDOM.textContent = this.#score;
this._randInArr();
this._nextQuestion(); // next to the Question
this._showImg(); // render img
}
_nextQuestion() {
btnAll.forEach((btn, i) => {
btn.removeAttribute('data-id');
btn.setAttribute('data-id', this.arr[i]); // Set Attribute [data-id, i]
btn.innerHTML = harryPotterName[this.arr[i]];
});
}
_showImg() {
divPicture.innerHTML = `
<img src="images/Players/${this.id}.jpg" />
`;
}
_init() {
scoreDOM.textContent = this.#score;
this._showImg();
}
}
new QuizzGame();
CodePudding user response:
The problem is here. Once you have an incorrect answer, this._incorrect() gets triggered which causes this.id to be changed. And after that another condition is being executed, so in this case this.id is already changed and it can pass the condition which is checking if the answer is correct.
_ButtonHandler(e) {
console.log( e.target.dataset.id, this.id);
if ( e.target.dataset.id !== this.id || this.#score <= 0) this._incorrect(); // incorrect Answer
if ( e.target.dataset.id === this.id && this.#score > 0) this._correct(); // correct Answer
}
You need to create a local variable of this.id inside your _ButtonHandler. In this case, even if this_incorrect() is called, it will not mutate this.id, and the execution of your _ButtonHandler will not depend on side effects.
_ButtonHandler(e) {
let capturedId = this.id // <- HERE
console.log( e.target.dataset.id, this.id);
if ( e.target.dataset.id !== capturedId || this.#score <= 0) this._incorrect(); // incorrect Answer
if ( e.target.dataset.id === capturedId && this.#score > 0) this._correct(); // correct Answer
}
