0

I want to pick a random element from an array without repeating, but an error occurred: Cannot read properties of undefined (reading 'sound').

Here's my code:

var words = [
 { word: 'major', sound: 'major.mp3'},
 { word: 'apply', sound: 'apply.mp3'},
 { word: 'blue', sound: 'blue.mp3' },
 { word: 'cat', sound: 'cat.mp3' },
 { word: 'class', sound: 'class.mp3'},
 { word: 'code', sound: 'code.mp3' },
 { word: 'cook', sound: 'cook.mp3' },
 { word: 'daisy', sound: 'daisy.mp3'},
 { word: 'ease', sound: 'ease.mp3' },
 { word: 'idea', sound: 'idea.mp3' }
];
var randomWord = words[Math.floor(Math.random() * words.length - 5)]; // just added - 5 here
var audio = new Audio();
var playBtn = document.getElementById("play-button");
var guessBtn = document.getElementById("guess-button");
var nextBtn = document.getElementById("next-button");
var correct = document.getElementById("correct");
var incorrect = document.getElementById("incorrect");
playBtn.addEventListener("click", function() {
 audio.src = randomWord.sound;
 audio.play();
 var name = words.splice(randomWord,1); // just added
 words.push(name); // just added
 })
guessBtn.addEventListener("click", function() {
 var inputBox = document.getElementById("input-box").value;
 if (inputBox == randomWord.word) {
 correct.innerHTML = "Correct!"
 }
 else {
 incorrect.innerHTML = "Incorrect"
 }
})
nextBtn.addEventListener("click", function() {
 location.reload();
})

The audio played smoothly until I attempted to make it not repeat. Am I doing it wrong?

asked Dec 21, 2021 at 3:36
2
  • Assuming you're trying to get a random number between 0 and the last index of words, you're not doing it correctly. Check out this section of the relevant docs. Commented Dec 21, 2021 at 3:40
  • You are returning a random number and then subtracting 5 from it (which could be a negative result). This is due to operator precedence. Put parentheses around words.length -5, of course you do realize this will only randomize up to 5. Commented Dec 21, 2021 at 3:41

2 Answers 2

1

words[Math.floor(Math.random() * (words.length - 1))];

I think you need to use like this.

because Math.floor(Math.random() * words.length - 5) can be less than 0

answered Dec 21, 2021 at 3:44
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the help, but it didn't quite work, sorry.
0

You may consider : 1) building an array of indexes from 0 to words.length, 2) picking a random index 3) getting a word using the random index (the word will be random) 4) deleting the random index to avoid repetitions. This way, you no dot not need to delete your words and your random index will always be valid.

//----------New code-----------------
var indexes = []
for (let i=0; i<words.length; i++) {
 indexes.push(i)
}
//-----------------------------------
 playBtn.addEventListener("click", function() {
 //get a random index value
 let randomIndex = Math.floor((Math.random()*words.length))
 //Get your randomword here, using the random index
 var randomWord = words[randomIndex]; 
 //Delete the index so it will not repeat
 indexes.splice(randomIndex,1)
 //This is your code below
 audio.src = randomWord.sound;
 audio.play();
 //var name = words.splice(randomWord,1); // delete this!
 words.push(name); // just added >> is this required?
 })
 
answered Dec 21, 2021 at 4:04

2 Comments

My audio played with this but still repeats.
Your code does not seem to update the random word. I edited my answer and moved the added code into the playBtn eventListener function. This way, when a user clicks the play button, a new random index and word will be chosen and played. The random index will be removed from the indexes array, to avoid repetition. Your code was not runnable locally, so I had to guess on the solution.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.