My jukebox application breaks after cycling through all songs - javascript

My jukebox application does not start over after going through all the songs in the playlist. Rather it stops functionality all together. So far it plays,pauses,stops,goes back, and next. The second it runs through the final song and I hit "next" nothing happens, nor does any other function work.
Jukebox.prototype.next = function() {
this.jamz[index].pause();
index++
this.jamz[index].currentTime = 0;
this.jamz[index].play();
if (index == this.jamz.length) {
this.jamz[index].currentTime = 0;
this.jamz[index].play();
}
}
Jukebox.prototype.back = function() {
this.jamz[index].pause();
index--
this.jamz[index].currentTime = 0;
this.jamz[index].play();
if (index == 0) {
this.jamz[index].currentTime = 0;
this.jamz[index].play();
}
}
This is the code that runs perfectly until it reaches the end of the final song. I am trying to get it to go back to the first song in my jamz array which has all my music on it.
The error in my console seems to be;
Uncaught TypeError: Cannot set property 'currentTime' of undefined
at Jukebox.next (script.js:55)

You could try re-ordering the code to check if you have reached the end of the playlist first - otherwise you'll get a javascript error and it will stop your program ie:
Jukebox.prototype.next = function() {
this.jamz[index].pause();
if (index == this.jamz.length-1) {
index=0;
} else {
index++;
}
this.jamz[index].currentTime = 0;
this.jamz[index].play();
}
Jukebox.prototype.back = function() {
this.jamz[index].pause();
if (index == 0) {
// rotate back from first track to last track
index = this.jamz.length-1;
} else {
index--;
}
this.jamz[index].currentTime = 0;
this.jamz[index].play();
}

I think you have to check the index if it is not out of the range from 0 to jamz.length - 1 before you call this.jamz[index].play()

Lists in js are 0 indexed, this meanse that the last item in a list has the index list.length-1.
In your case you need to change index == this.jamz.length to index == this.jamz.length-1. Also, for good mesure, you should never use == if you can help it. The == operator in js is not the same as the == operator in other languages. You want to use the === operator.
Jukebox.prototype.next = function() {
this.jamz[index].pause();
index++
this.jamz[index].currentTime = 0;
this.jamz[index].play();
if (index === this.jamz.length-1) {
this.jamz[index].currentTime = 0;
this.jamz[index].play();
}
}
Jukebox.prototype.back = function() {
this.jamz[index].pause();
index--
this.jamz[index].currentTime = 0;
this.jamz[index].play();
if (index === 0) {
this.jamz[index].currentTime = 0;
this.jamz[index].play();
}
}

You are surpassing the length of the array and you aren't setting the next song when it reaches the end of the playlist.
Jukebox.prototype.next = function() {
this.jamz[index].pause();
this.jamz[index].currentTime = 0;
//Check if you are at the end of your playlist
if (index === this.jamz.length - 1) {
index = 0;
}else{
index++;
}
this.jamz[index].currentTime = 0;
this.jamz[index].play();
}

Related

Click listener firing multiple times in react [duplicate]

I add event handlers to all my inputs in a sudoku game using addEventListener.
Every time that I write a number inside an input handler is running 3 times, why?
I want it to run only once for each element.
How can I do that?
// passing the board game
function addListener(game) {
counter = 0;
for (let i = 0; i < 81; i++) {
//add evenListener to all the input filds
document.querySelectorAll('input')[i].addEventListener('input', function() {
//save the innerHtml of the value that we write
let inputInnerHTML = Number(this.value);
//save the id of the input that we write in
let index = this.id;
checkIfCorrect(inputInnerHTML, index, game)
})
};
}
function checkIfCorrect(inputInnerHTML, index, game) {
for (let i = 0; i < game.length; i++) {
//if the original number is the same, the number will be black
if (inputInnerHTML === 0) {
// if the input is erased remove the classes
document.getElementById(index).classList.remove('wrong');
document.getElementById(index).classList.remove('correct');
}
if (game[i] === inputInnerHTML) {
document.getElementById(index).classList.add('correct');
break;
} else if (game[i] !== inputInnerHTML && inputInnerHTML !== 0) {
//if the number is not the same, the number will be red
//and if we did not erase the number add red and count
document.getElementById(index).classList.add('wrong');
counter++
if (counter === 1) {
document.getElementById('mistakes').innerHTML = 'Mistakes: 1/3';
}
if (counter === 2) {
document.getElementById('mistakes').innerHTML = 'Mistakes: 2/3';
}
if (counter === 3) {
//go to you lose
document.getElementById('mistakes').innerHTML = 'Mistakes: 3/3';
youLose();
}
}
}
}
You are calling addEventListener every time you select a difficultyButton. This means that each time you click a button, you'll be adding an eventListener.
Fix this by calling removeEventListener, before calling addEventListener.
I think the problem is the checkIfCorrect function, after it is detected correct or not it doesn't stop and keep searching creating confusion.
By adding the break to the else if we block the search if the error has already been detected and notified.
function checkIfCorrect(inputInnerHTML, index, game) {
for (let i = 0; i < game.length; i++) {
//if the original number is the same, the number will be black
if (inputInnerHTML === 0) {
// if the input is erased remove the classes
document.getElementById(index).classList.remove('wrong');
document.getElementById(index).classList.remove('correct');
}
if (game[i] === inputInnerHTML) {
document.getElementById(index).classList.add('correct');
break;
} else if (game[i] !== inputInnerHTML && inputInnerHTML !== 0) {
//if the number is not the same, the number will be red
//and if we did not erase the number add red and count
document.getElementById(index).classList.add('wrong');
counter++
if (counter === 1) {
document.getElementById('mistakes').innerHTML = 'Mistakes: 1/3';
}
if (counter === 2) {
document.getElementById('mistakes').innerHTML = 'Mistakes: 2/3';
}
if (counter === 3) {
//go to you lose
document.getElementById('mistakes').innerHTML = 'Mistakes: 3/3';
youLose();
}
break; // FIX
}
}
}

isMatch() function not working correctly in JavaScript

I am trying to use an empty array which fills when clicking on an image send the Image ID to a findMatch() function which in turn is used to insert the a match in a isMatch() function. My isMatch() function is not working correctly. I have tried debugging in Chrome but this is not helping. Any help or advice would be appreciated. I need to clear the array after 2 images are selected.
function isMatch() {
if ((count === 1) && (pic == 1)) {
cMatch.unshift(arrMatch);
match1 = imgID;
}
if ((count === 2) && (pic == 1)) {
// var index2=deClick(clicked);
cMatch.push(arrMatch);
match2 = imgID; {
if (cMatch[0] === cMatch[1]) {
bMatch = true;
cMatch.length = 0;
cMatch = [];
count = 0;
match1 = 0;
match2 = 0;
} else {
bMatch = false;
document.getElementById(match1).src = defaultImage;
document.getElementById(match2).src = defaultImage;
cMatch.length = 0;
cMatch = [];
count = 0;
match1 = 0;
match2 = 0;
}
//else{bMatch=false;}}
}
if (count > 2) {
document.getElementById(match1).src = defaultImage;
document.getElementById(match2).src = defaultImage;
count = 0;
return bMatch;
}
}
}
The code when stepping in Chrome seems to work but when I use in the browser it does not work at all.

Pop up a warning when the same item is entered twice on a sales order when the order is created/edited

I am trying to do a pop-up warning before the sales order is saved if the exact same item is entered twice when the order is created/modified on Netsuite. However, there is no window popping up and I am not sure what is wrong with the script. Here is what I got:
function validateitem (type){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (type == 'item' && numLine > 0) {
for(var i = 0; i < numLine; i++) {
var itemSO = {};
itemSO.id = nlapiGetLineValue('item','item',i);
if (itemSO.id != null && itemSO.id !=''){
for (var j = 0; j < numLine; j++){
if(itenArr.indexOf(itemSO[i].id) === -1) {
itemArr.push(itemSO[i].id);}
else{
if (!confirm('You have entered a duplicate item for this sales order. Continue?'))
{
flag = false;
}
}
}
}
}
}
return flag;
}
Can somebody help, please?
Here is a slightly edited version:
function validateitem (){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (numLine > 0) {
for(var i = 1; i <= numLine; i++) {
var itemSO = nlapiGetLineItemValue('item','item',i);
if (itemSO != null && itemSO !=''){
for (var j = 1; j <= numLine; j++){
if(itemArr.indexOf(itemSO[i]) === -1) {
itemArr.push(itemSO[i]);}
else{
flag = false;
}
}
}
}
}
if (flag == false){
alert('You have entered the same item twice.Continue?');
}
return flag;
}
This is the complete after-edit code that works:
function validateitem (){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (numLine > 0) {
for(var i = 1; i <= numLine; i++) {
var itemSO = nlapiGetLineItemValue('item','item',i);
if (itemSO != null && itemSO !=''){
for (var j = i+1; j <= numLine; j++){
var itemSOplus = nlapiGetLineItemValue('item','item',j);
if(itemSO === itemSOplus) {
flag = false;
}
}
}
}
}
if (flag == false){
alert('You have entered the same item twice.Continue?');
}
return flag;
}
Thanks to Krypton!!
As per SuiteAnswers ID 10579, there are no paramters passed to the saveRecord client event. Therefore when your code checks the following:
if (type == 'item' && numLine > 0)
it finds that type equals undefined, so the condition is not met and the code will jump straight down to return flag which has been set to true.
Also note that in SuiteScript 1.0, line indexes start from 1 - not 0 as your code seems to assume.
EDIT - adding comment to form part of this answer:
I'd like to understand your logic behind itemSO[i] - as itemSO is not an array. Why not just compare the item from the current line of the inner loop with the current line of the outer loop and set the flag false if they match? Also, the inner loop need only start from j = i + 1 as the previous lines would have already been compared.

after a variable change to 1, call something.. javascript

So Basicly if i click the burtton, it should change the variables to 1.
However, it dosen't print out "It's happening now" as it should.
Could someone please explain what's wrong with this??
Best regards daniel.
var reg_uname_done = 0;
var reg_pword1_done = 0;
var reg_pword2_done = 0;
var reg_email_done = 0;
$("#first_nav_bar li:first").click(function(event) {
reg_uname_done = 1;
reg_pword1_done = 1;
reg_pword2_done = 1;
reg_email_done = 1;
});
if(reg_pword1_done === 1 && reg_pword2_done === 1 && reg_email_done === 1 && reg_uname_done === 1) {
console.log('its happening now');
}
The reason why this is not happening is b/c the js file is going down, and you haven't "clicked" the <li> element yet, therefore your variables are still equal to 0. You have to set a function inside of that event.
See fiddle
var reg_uname_done = 0;
var reg_pword1_done = 0;
var reg_pword2_done = 0;
var reg_email_done = 0;
$("#first_nav_bar li:first").click(function (event) {
reg_uname_done = 1;
reg_pword1_done = 1;
reg_pword2_done = 1;
reg_email_done = 1;
check();
})
function check() {
if (reg_pword1_done === 1 && reg_pword2_done === 1 && reg_email_done && reg_uname_done) {
console.log('its happening now');
}
}

Boolean's value is acting as true but is listed as false?

I'm creating a simple tic-tac-toe game and I have a boolean called winAlert that if it is true it should alert the player that they have won. This works correctly for the most part, but there is one instance where it does not. If the game is won and all of the cells are filled, the console logs that winAlert's value is false, but it still alerts the player that they have won, as if it were true. Could someone look over this code and see why this is behaving in this way? http://jsfiddle.net/Z5c9P/3/
This function is where I think the problem lies, but I don't know for sure.
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
for (var j = 0; j < winConditions[i].length; j++) {
winAlert = false;
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
winAlert = true;
break;
}
}
if (!winAlert) break;
}
if (winAlert) {
alert(currentPlayer + " wins!");
break;
}
}
};
Here's the code that calls this function:
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
This is happening because your code does the following:
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
So if X ever wins the game, determineWin(xMoves) will set the variable to true, and determinWin(oMoves) will set it back to false, all before the console.log()
One way to solve this would be to only check for a win for the current player's moves:
storeMoves();
determineWin(currentPlayer == 'X' ? xMoves : yMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
You have called determineWin on each player. so if x wins, determineWin(oMoves); will make winAlert false. Is this the problem?
Maybe you should create a new determineWin which only called once to determine who is the winner.
this code will just skip another user(so winAlert is still true) when his cell is less than 3, so this problem doesn't need fill all cells but just each player has more than 3 cells.
if (winConditions[i].length > pMoves.length) {
continue;
}
i change a little your code Fiddle
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
winAlert = false;
matches = 0;
for (var j = 0; j < winConditions[i].length; j++) {
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
matches++;
}
}
}
if (matches == 3) return true;
}
return false;
};
and then
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
if (determineWin(xMoves)){ // this is changed
alert("X Win")
return;
};
if (determineWin(oMoves)){
alert("O Win")
return;
};
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
** Updated to clarify

Categories