How to break from Jquery click callback function


#1

I am making my own version of simon Game, but the callback function inside click is not existing after user press wrong input. As a result function handler.patternRepeatPlayer() is getting called recursivelly for each element of array pattern.
I want a solution to break from the else after calling handler.patternRepeatPlayer just once.
The program is working fine in strict mode, but only in non-strict mode inside else , I am not
able to break from else.

The flow is like from html -> Function simonnGame.PatternGen from PatternGen -> handler.PatternRepeatPlayer -> PatternRepPlayer -> PatternMatcher -> userInput(here if wrong user input in non-strict mode) -> patternRepeatPlayer This case is failing as in this case else is not existing after calling the function only once.
can access the project on Git -


I think there is some misunderstanding on how click callback functions work.

//code

var simonGame = {
	COUNT: 0,
	PATTERN: [],
	SOUND:[{file:'sounds/sa.mp3'},{file:'sounds/re.mp3'},{file:'sounds/ga.mp3'},{file:'sounds/ma.mp3'},{file:'sounds/pa.mp3'},{file:'sounds/dha.mp3'},{file:'sounds/nee.mp3'}],
	patternGen: function(){
		var randomId;
		randomId = Math.floor(Math.random() * 7);
		simonGame.PATTERN.push(randomId);
		if(simonGame.COUNT > 20){
			alert("You have won the game!!");
			window.location.reload(true);
		}
		simonGame.COUNT += 1;
		//debugger;
		//console.log("increase count true calling count display " + simonGame.COUNT);
		handler.countDisplay();
		//console.log("count gen true calling patternPlayer with PATTERN " + simonGame.PATTERN );
		handler.patternRepeatPlayer();
	}, //close patternGen
	patternMatcher: function(genPattern){
		//console.log("inside patternMatch");
		var genPattern = simonGame.patternGen;
		//setTimeout(function(){
			//console.log("PATEERN: " + simonGame.PATTERN + "COUNT " + simonGame.COUNT );
			//calling user input
			console.log("calling user Input");
			handler.userInput();
			setTimeout(function(){
				if(handler.repeatFlag === false){  //execute count gen only if repeat flag is false inside user INPUT
					genPattern();
				}
			},simonGame.COUNT*2000);
		 
			//console.log("pattern check true, calling pattern gen");
			
		//},simonGame.COUNT*5000); //close setTimeout
		
	}, //close patternMatcher
	
	
	
} //close simonGame

var handler = {
	countRepPlayer: 0,
	repeatFlag: false,
	patternRepeatPlayer: function(){
		var repeater = setInterval(function(){
				handler.effect(simonGame.PATTERN[handler.countRepPlayer]);
				handler.countRepPlayer += 1;
				if(handler.countRepPlayer > simonGame.COUNT){
					clearInterval(repeater);
					//setTimeout(function(){
						simonGame.patternMatcher();
						//},1000);
					handler.countRepPlayer = 0;
				}
			},1000);//close sestInterval
		
	}, //close patternRepeatPlayer
	effect: function(id){
	   var img = document.getElementById(id);
	   if(img !== null && id !== undefined){
			$( img ).fadeIn(100).fadeOut(100).fadeIn(100);//fadeOut(200).fadeIn(200);
			//debugger;
			var audio = new Audio(simonGame.SOUND[id].file);
			audio.play();
			//console.log("id inside effect " + id)
		}
	},//close effect
	countDisplay: function(){
		document.getElementById("count").innerHTML = "Count: " + simonGame.COUNT;
	}, //close countIncrease
	userInput: function(){
		var userPattern = new Array();var id;
		 $('img').click(function(){						
				id = parseInt(this.id,10);
				userPattern.push(id);
				handler.effect(id);
				console.log(" user " + userPattern); 
				console.log(" pattern " + simonGame.PATTERN);
				if(userPattern.indexOf(id) !== simonGame.PATTERN.indexOf(id)){
					console.log(" WRONG USER INPUT ");
					if($('.chkStrict:checked').val() === "on"){
						var audio = new Audio('sounds/wrong.mp3');
						audio.play();
						setTimeout(function(){window.location.reload(true)},1000);
					} else {
						console.log("inside else " );
						var audio = new Audio('sounds/wrong.mp3');
						audio.play();
						userPattern.length = 0;
						handler.repeatFlag = true;
						handler.patternRepeatPlayer(); //this is getting called recursivelly rather than quiting after calling once.
						return ;
					}
				}
				//reset the userPattern Array
				if(userPattern.length === simonGame.PATTERN.length){
					userPattern.length = 0;
				}
		});		//close click.
					
	}
	
	
} //close handler

#2

Please be sure to surround code samples with a line of three backticks (above the ESC key) and follow your code with the same line of three backticks. I’ve added it to your post to make it readable.


#3

Do you have this in a codeped or something where we can see what’s happening? One of the reasons FCC recommends that it makes it sooooo much easier for people to help you with problems.

When I download this to my computer and run it, the first thing i notice is that it’s telling me I’m wrong, even when I give the right answer. It seems to log the click correctly but your logic calls it “wrong”. I’d look at that first.

It seems to me (on a quick look, gotta go for my run before it gets too hot) that the click is firing multiple times. Have you tried something like:

		 $('img').click(function(e){
			 e.stopImmediatePropagation(); 
			 e.preventDefault();

This will keep the click from accidentally firing again. Now, when I run it, and I hit a wrong answer (every answer is wrong, as I mentioned), it plays it twice, presumably one for my press and once for the replay (though you might want a delay in there.) This is an improvement from when it kept building up calls and calling it over and over.

Just as a point definition, I don’t think we’re talking about recursion here, where a function calls itself.


#4

I have shared the url of git repo of this project. Its capturing the user input correctly, only thing is there is delay when the function to check user input after pattern repeat may be because of that you have come across a case where right input is also coming wrong.

But I have not come across such case though I can try immediate propagation and see what happens.

main issue I think can be with setInterval patternRepater which is making multiple calls to patterRepeatPlayer and then to function userInput for one wrong input. that is why the program in non strict mode is not working.

Thanks for taking time to check my problem and suggest solution.


#5

I won’t debug this, but you can “break” from any function with a return statement. You should probably find some way to stop the recursive calls, though.


#6
<p> I have solved this problem by moving away from jquery , and simply 
   setting event handler on divs by wrapping each image inside one div using 
   java script. Below is the sample code. 

//code

handler.divs.forEach(function(div){ 
                var img = document.getElementById(div);
                img.onclick = function(){
                    var id = parseInt(img.id,10);
                    userPattern.push(id);
                    handler.effect(id);
                    console.log(" div clicked " + id + " u p " + userPattern);
                    if(userPattern.indexOf(id) !== simonGame.PATTERN.indexOf(id)){
                        console.log(" if ");
                        handleWrongInput();
                    } else if(userPattern.length === simonGame.PATTERN.length){
                        setTimeout(function(){simonGame.patternGen({result:"success"})},1200);
                    }
                }

        }); console.log(" up " + userPattern + " SGP " + simonGame.PATTERN);</p>