If statement not executing correct code? - javascript

So I am trying to develop a Tic Tac Toe game for practice with javascript but I've hit a roadblock. I have an if statement that should be returning true but it isn't. Here is a sample.
var game = true;
var x = 'X';
var o = 'O';
var blank = '';
var turn = x;
var board = [blank, blank, blank,
blank, blank, blank,
blank, blank, blank];
function write() {
$('td').click(function() {
//Making sure that the block that was clicked can only be clicked once
var id = $(event.target).attr('id');
var digit = parseInt(id.slice(-1));
//check to see of the block has been clicked on
if (board[digit] = blank) {
board[digit] = turn;
$(board[digit]).html(turn.toUpperCase());
if (turn = x) {
turn = o;
} else if (turn = o) {
turn = x;
}
} else {
alert("That box has already been clicked on!")
}
});
}

You have two issues at first glance.
First, event is undefined. Define it as a function parameter in your .click call.
$('td').click(function(event) { /* rest of the code */ }
Second, as Pointy commented, = is for assignment, == and === are meant for comparisons.
Thus
if (board[digit] = blank) { /**/ }
needs to be
if (board[digit] === blank) { /**/ }
Regarding the difference between == and === you can get more information here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
Short version, prefer === unless you're absolutely sure you know what you're doing and want to explicitly use ==.

if (board[digit] === blank) {
^^

Related

Why do I have to IF return, IF what?

I am learning to code or rather - even reading the code at this moment.
Could anyone please explain me, why those lines are there and what do they do?
if (noClicking) return;
if (e.target.classList.contains("flipped")) return;
What is the purpose of those two lines?
function handleCardClick(e) {
// you can use event.target to see which element was clicked
if (noClicking) return;
if (e.target.classList.contains("flipped")) return;
let currentCard = e.target;
currentCard.style.backgroundColor = currentCard.classList[0];
if (!card1 || !card2) {
currentCard.classList.add("flipped");
card1 = card1 || currentCard;
card2 = currentCard === card1 ? null : currentCard;
}
if (card1 && card2) {
noClicking = true;
// debugger
let gif1 = card1.className;
let gif2 = card2.className;
if (gif1 === gif2) {
cardsFlipped += 2;
card1.removeEventListener("click", handleCardClick);
card2.removeEventListener("click", handleCardClick);
card1 = null;
card2 = null;
noClicking = false;
} else {
setTimeout(function() {
card1.style.backgroundColor = "";
card2.style.backgroundColor = "";
card1.classList.remove("flipped");
card2.classList.remove("flipped");
card1 = null;
card2 = null;
noClicking = false;
}, 1000);
}
}
if (cardsFlipped === COLORS.length) alert("game over!");
}
if (noClicking) return;
if (e.target.classList.contains("flipped")) return;
The lines below those 2 lines will not be executed if one of the 2 lines are returned.
It means if noClicking == true or e.target.classList.contains("flipped") == true, then all the lines below those 2 lines will not be executed.
While the answers already given are correct, I thought it could help to understand why those lines are there in place. They are called guard clauses. Their purpose is to make your code more efficient.
Think of a scenario like this:
function myFunc(someParam) {
/*
do something that takes a lot of time/resources
... then somewhere you find someParam was invalid!
so all the calculations done until now was useless
*/
}
So instead of checking the validity of arguments, global variables, etc. when you need them in the function, you check for them in the beginning of the function such as like this:
function myFunc(someParam) {
//let's say valid() is a function that checks for validity of the param,
//returns true if valid, false if invalid.
if(!valid(someParam)) return;
/*
do something that takes a lot of time/resources
... then your function will only run the expensive code
if it is sure that there are no invalid arguments passed to it.
*/
}
It doesn't always have to be just return. This is your choice. Maybe the function always returns some positive number, then you could return -1 as such:
const getRoot = (num) => {
if(num < 0) return -1;
//get square root of the number
return abs(Math.sqrt(num));
}
//Then when you call the function, you could check if the result is not -1,
//to make sure you passed the correct arguments.
if (getRoot(-1) < 0)
console.error("Uh oh, you passed a negative number to the square root function");
Or you could throw an Error:
function myFunc (someParam) {
if(!valid(someParam)) throw new Error("wrong param bruh");
//do something...
}

User clicks too fast bug

first of all i'm pretty new to JS.
i'm trying to make a memory game but i have the next problem.
the code :
function cardClicked(elCard) {
// If the user clicked an already flipped card - do nothing and return from the function
if (elCard.classList.contains('flipped')) {
return;
}
// Flip it
elCard.classList.add('flipped');
// This is a first card, only keep it in the global variable
if (elPreviousCard === null) {
elPreviousCard = elCard;
} else {
// get the data-card attribute's value from both cards
var card1 = elPreviousCard.getAttribute('data-card');
var card2 = elCard.getAttribute('data-card');
// No match, schedule to flip them back in 1 second
if (card1 !== card2) {
setTimeout(function () {
elCard.classList.remove('flipped');
elPreviousCard.classList.remove('flipped');
elPreviousCard = null;
}, 1000)
wrongPick.play();
} else {
// Yes! a match!
flippedCouplesCount++;
elPreviousCard = null;
rightPick.play();
}
}
i would like to prevent the user from clicking more then two times (it's a memory game.) can someone tell me how can i implement this into my code please?
You can set a global variable to isClickable initially set to true, enter the code check if its true, if it isn't, return, else go ahead and set it to false and do a timeout to set it to true again, like:
var isClickable = true;
function cardClicked(elCard) {
if (!isClickable) return;
isClickable = false;
setTimeout(function () {
isClickable = true;
}, 500)
...
Since it's a card game I would do the following:
Make array of elements:
var cards = (
{
"card":"numberOfCard",
"isclicked" :"yes/no"
}
);
And then every time somebody clicks on card I would change isClickable to no so next time event occures I would prevent it.
create variable for example opened_cards that store how many card opened, if less than 2 allow open another card else do nothing.
var opened_cards = 0;
function cardClicked(elCard) {
// do check here
if (opened_cards < 2) {
// less than 2 card opened do operation
opened_cards++;
if (elCard.classList.contains('flipped')) {
return;
}
// Flip it
elCard.classList.add('flipped');
// This is a first card, only keep it in the global variable
if (elPreviousCard === null) {
elPreviousCard = elCard;
}
else {
// get the data-card attribute's value from both cards
var card1 = elPreviousCard.getAttribute('data-card');
var card2 = elCard.getAttribute('data-card');
// No match, schedule to flip them back in 1 second
if (card1 !== card2) {
setTimeout(function() {
opened_cards -= 2;
elCard.classList.remove('flipped');
elPreviousCard.classList.remove('flipped');
elPreviousCard = null;
}, 1000);
wrongPick.play();
}
else {
// Yes! a match!
opened_cards = 0;
flippedCouplesCount++;
elPreviousCard = null;
rightPick.play();
}
}
}
}

What does "/^\s*$/" mean in this javascript?

I have this javascript that works well in my PDF form to set a field as required if another field contains data. However, I want to have it ignore a value of "0.00" for the test. But I do not know what /^\s*$/ means let alone how to alter the script for my condition.
var rgEmptyTest = /^\s*$/;
// t is the value to be tested and f is the field to set accordingly
function testMyField (t, f) {
if (rgEmptyTest.test(t)) {
this.getField(f).required = false;
} else {
this.getField(f).required = true;
}
}
Thank you!
In your piece of code there is a function that uses regex
A javaScript regExp reference for you.
Thanks #j08691 for the link that explains and let you test the regex used (regexr.com/3rf9u).
You can change your code like this to make a logical exception
var rgEmptyTest = /^\s*$/;
var rgTest = /0.00/;
// t is the value to be tested and f is the field to set accordingly
function testMyField (t, f) {
if (rgEmptyTest.test(t) || rgTest.test(t)) {
this.getField(f).required = false;
} else {
this.getField(f).required = true;
}
}
I guess it should work
\s means space
* Means any number
" " This is empty
" " This too
I think I got this to work:
var rgEmptyTest = /^\s*$/;
var rgTest = /^[0\.00]$/;
// t is the value to be tested and f is the field to set accordingly
function testMyField (t, f) {
if (rgEmptyTest.test(t) || rgTest.test(t)) {
this.getField(f).required = false;
} else {
this.getField(f).required = true;
}
}
Thank you #Higor Lorenzon and #j08691!

Syntax Error in Basic Javascript Function

I keep getting errors when debugging in IE.
This is a basic hide function.
idHide is the id of the field to be hidden
idCondition is the id of the reference field the condition is compared upon
value is the value that would satisfy the condition
function hideOnCondition(idHide, idCondition, value)
{
if (document.getElementById[idCondition] = value)
{
document.getElementById(idHide).style.display = "none";
}
else
{
document.getElementById(idHide).style.display = "";
}
}
I always encounter the error in:
if (document.getElementById[idCondition] = value)
"the value of the property is null or undefined not a function object"
Then I tried changing "getElementById" with "all". then changed the brackets to parentheses, still nothing, only for the line to be highlighted in yellow.
Im sorry, I'm just stumped. Again, thank you all for understanding.
You were using square brackets instead of parentheses
=== should be used for comparing not =
.
function hideOnCondition(idHide, idCondition, value)
{
if (document.getElementById(idCondition) === value) // <- fix here
{
document.getElementById(idHide).style.display = "none";
}
else
{
document.getElementById(idHide).style.display = "";
}
}
function myFunction(option, value, div) {
//get the element you want to hide by it's ID
var x = document.getElementById(div);
//if the option you selected is coresponding to the given value
//hide the earlier selected element
if (option === value) {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
This should do it.
Instead of an assignment you should use the comparison operator Identity / strict equality (===):
function hideOnCondition(idHide, idCondition, value) {
const result = document.getElementById[idCondition] === value ? 'none' : '';
document.getElementById(idHide).style.display = result;
}
Two issues I could see
using = instead of === and not comparing value instead only comparing the the output of document.getElementById[idCondition] with value.
using [] instead of invoking the function using ()
Although, none of these would cause the syntax error as you have claimed in your post.
You can simplify it as
var getEl = (id) => document.getElementById(id);
function hideOnCondition(idHide, idCondition, value)
{
getEl(idHide).style.display = getEl(idCondition).value == value ? "none" : "";
}

If checbox/disable element not working properly

I'm attempting to make a script so that if you check/uncheck a checkbox input, that it will enable/disable a target input text box. My code if statement doesn't seem to function correctly sometimes firing both ifs at once, other times not firing at all. I've done debugging and tried numerous variations but it still won't work. Here is what I have, any help is greatly appreciated!
function disable(elem) {
var obj = document.getElementById(elem);
status = obj.disabled;
console.log(status);
if (status = true) {
console.log("test");
obj.disabled = false;
obj.style.backgroundColor = "white";
}
if (status = false) {
console.log("test2");
obj.disabled = true;
obj.style.backgroundColor = "bfbfbf";
}
}
This code is not exhibiting proper behavior for several reasons.
The first reason is that your if statements are inline, not in an if-else form. A better organization is as follows:
function disable(elem) {
var obj = document.getElementById(elem);
status = obj.disabled;
console.log(status);
if (status == true) {
console.log("test");
obj.disabled = false;
obj.style.backgroundColor = "white";
} else {
console.log("test2");
obj.disabled = true;
obj.style.backgroundColor = "#bfbfbf";
}
}
This means that even if the variable you are checking changes while the code in the block is executing, it will not execute the code in the opposing block regardless of its new value. As you have it, if the value were to change while the code in the first if statement was running, then it is possible for both control blocks to run.
The second reason it is not behaving right is due to the incorrect syntax within your if statement. You are currently using the = operator which means set the variable to what you are wanting to check against. You must use either the == or === equality checks (the latter is type strict) if you want to write them this way. An even better way is to omit that operator entirely by just checking if the value is truthy, like so:
function disable(elem) {
var obj = document.getElementById(elem);
status = obj.disabled;
console.log(status);
if (status) {
console.log("test");
obj.disabled = false;
obj.style.backgroundColor = "white";
} else {
console.log("test2");
obj.disabled = true;
obj.style.backgroundColor = "#bfbfbf";
}
}
This should give you your expected control behavior :) As was mentioned, make sure you are formatting your values appropriately (e.g. "#bfbfbf" not "bfbfbf")

Categories

Resources