if(xxx || xxx), what am I doing wrong? - javascript

Can someone explain to me what am I doing wrong?
function navMenuIntervalCheck() {
if (currentSiteUrl != "subsites/players.php" || currentSiteUrl != "subsites/itemshop.php") {
$.ajax({
url: currentSiteUrl,
cache: false,
success: function (dataForContainer) {
$('#container').html(dataForContainer);
}
});
}
screenControlCheck();
};
setInterval(function () {
navMenuIntervalCheck()
}, 5000);
When I run my website it refreshes even when currentSiteUrl==subsites/players.php

As x!='a' || x!='b' is always true, I guess you wanted && instead of ||.
Read || as OR and && as AND.
More details in the MDN on logical operators.

currentSiteUrl can only have one value, so it will always be that at least one of the values you're testing will not equal currentSiteUrl, making the if condition always true.
I think you meant to use && or you meant to do == with ||.

Your code says this :
Refresh when currentSiteUrl is different than subsites/players.php or different than subsites/itemshop.php.
So subsites/players.php is indeed different than subsites/itemshop.php
Use && instead of ||

Look at your if statement:
if (a != foo || a != bar)
Lets look at the possibilities:
a = foo. This will evaluate as true, because a != bar
a = bar. This will evaluate as true, because a != foo
a = anything else. This will evaluate as true, because a != foo
Your if statement always evaluates to true.
As others have already said, you want to replace your || with &&.
Let me throw a logical rule at you, called DeMorgan's Law. It's really useful when learning how to set up a good if statement.
!(a || b) === !a && !b
also
!(a && b) === !a || !b
What that says is: "Not (one event or another)" is the same thing as "Not one event and not another", and "Not (one event and another)" is the same thing as "Not one event or not the other".

I know this has been answered but thought it might help to add some additional information using your own code.
As said, switching logical operator from || to && will work:
if (currentSiteUrl != "subsites/players.php" && currentSiteUrl != "subsites/itemshop.php")
But why is that?
Using ||
The || logical operator returns true if either the first or second expression is true and only if both are false will it return false.
Hence:
if currentSiteUrl != "subsites/players.php" is true you end up in the if block
if currentSiteUrl != "subsites/players.php" is false and currentSiteUrl != "subsites/itemshop.php" is true you end up in the if block
There will never be another scenario as your variable currentSiteUrl can only hold a single value and as such one of the expressions will always be true causing you to always end up in the if block.
Using &&
Using the && logical operator on the other hand though returns false if either the first or second expression is false and only if both are true will it return true.
Hence:
if currentSiteUrl != "subsites/players.php" is true and currentSiteUrl != "subsites/itemshop.php" is true you end up in the if block
if currentSiteUrl != "subsites/players.php" is true and currentSiteUrl != "subsites/itemshop.php" is false you don't end up in the if block
if currentSiteUrl != "subsites/players.php" is false you don't end up in the if block
There will never be another scenario, because only if both expression are true will you end up in the if block and as soon as either expression is false will you not.

How are you getting the currentSiteUrl. A url is followed by protocol:://domain
Try using the follwoing property to get URL and then match it
window.location.href
This url will also include the http or https and domain name

Related

Why is the result different from what I expect?

emptyWord = '';
if (emptyWord !== false) {
console.log(1);
} else {
console.log(2);
}
If emptyWord is false, I want the else to run. If emptyWord is true, I want the console.log(1) to run.
I actually expected console.log(2) to run. Because emptyWord is a falsey value. The condition says, 'is a falsey value, not the same as false'. The answer to that is 'no/false'.
I know a better thing to put would've been: emptyWord === true.
But whilst we're here, how do you explain in words what's going on with the condition in the snippet. I think I read somewhere that you should try to avoid 'double-negatives'.
You used !== false and not != false. When you use !== it isn't checking for "falsy", it's checking if it is actually false or not.
console.log('' != false);
console.log('' !== false);
it will always return true, because :
emptyword is not STRICTLY equals (=== means strictly equals) to false!
what you're probably looking for is !=, in this case it will convert the value 0 to false, for example. To note here, there is a difference between strictly equals and just plain equals (=== vs ==).
in english:
is emptyword not equal to false? in this case it is true, so it enters the first clause:
console.log(1);
take a look here for more examples :
https://j11y.io/javascript/truthy-falsey/
You should use !=false because !==false is strictly looking for not false
emptyWord = '';
if (emptyWord != false) {
console.log(1);
} else {
console.log(2);
}
The !== operator checks if the type and the value of the variables are the same.
The != operator checks if only the value is the same.
'' and false are equals the same in terms of value in js, but '' is a string and false is a boolean value.
If you want to get 2 as return, you need to change your code to:
emptyWord = '';
if (emptyWord != false) {
console.log(1);
} else {
console.log(2);
}
('' !== false) is true.
('' != false) is false.

Lost in javascript comparisons

I'm writing a script to be executed when my body element hasn't got any of the following classes:
a OR b OR c AND d
I tried this, but it doesn't seem to do the trick:
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || ((!($('body').hasClass('c')) && (!$('body').hasClass('d'))))) {
}
UPDATE
This seems to work:
if (!($('body').hasClass('a') || $('body').hasClass('b') || $('body').hasClass('c') && $('body').hasClass('d'))) {
}
use
$(function(){
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || !($('body').hasClass('c') && $('body').hasClass('d'))) {
}
});
You are looking for a body that doesnt have any of the classes, so you need to use &&. Heres what happens:
if(hasclass(a) || hasclass(b)) = if(true OR false) = if(true)
Above the OR operator || means that once it hits a true evaluation, it will execute your if-block.
if(hasclass(a) && hasclass(b)) = if(true AND false) = if(false)
Here the AND operator && means that once you hit a false evaluation, you block won't be executed.
You want the last thing to happen, since you want it to have neither of the classes. Learn how to play with these operators as they can be very confusing. As long as you remember that the AND operator will execute only if all statements are true and the OR operator will only execute if one of the statements is true. Nested operators work the same, so if((a = b && b = c) || (a = c)) will execute if a,b and c are the same OR when a and c are the same, but not when a and b are the same or a and c are the same.
More on expression and operators (specifically Bitwise and a must read): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators

javascript if conditional: object exists and has a value appended

Getting an 'Invalid left-hand side in assignment' error in my console. Am I missing syntax here?
if ($images[next] && images[next].loaded = false){
//stuff
}
Each condition passes on it's own, but fail when combined.
Using a single = means you're assigning a value to a variable. For comparisons, use == or === for strict equality.
Use double equals for comparison. Alternatively, you could just write:
var item = $images[next];
if (item && !item.loaded){
}
it should be
if ($images[next] && $images[next].loaded == false){
//stuff
}
Or Better
var images = $images[next];
if (images && images .loaded === false){
//stuff
}
As everybody already told you, you should be using == (or ===) for comparison. What caused the error is that the assignment operator = has a lower precedence than the boolean && operator, unlike == or any other comparison operator. So your expression was evaluated as:
($images[next] && images[next].loaded) = false
The left-hand part, in parentheses, will be either true or false. So that becomes either
true = false
or
false = false
Neither is allowed, because you can't assign anything to a boolean value (only to a variable or object property). Hence an Invalid left-hand side in assignment error is thrown.
When you use a proper comparison operator, the precedence rules cause it to be evaluated like this:
$images[next] && (images[next].loaded == false)
That becomes true && true, or true && false, or false && false, or false && true, then eventually just true or false, which is what an if statement expects.
Maybe a "==" instead of a "=" in the equality check would help
if ($images[next] && images[next].loaded == false)
{
//stuff
}
For a list of the javascript comparison operators, have a look here
Everyone'll prly say the same thing: ... .loaded = false should be ... .loaded == false. = is an assignment operator, == is a comparative operator..
Sometimes you'll see if (x = someFunction()) which will run the code block as long as someFunction() doesn't return false or throw an error (as it does in your case).
Let me know if you have any questions :)
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Expressions_and_Operators

javascript if condition with multiple ifs

I'm running a UI component on every page and on one of the pages, there's an extra functionality linked to it. The UI component has a boolean called MyValue and the extra functionality has an object called ExtraObject and one of its properties is a boolean called ExtraBool.
I want to test if MyValue is true AND if ExtraObject.ExtraBool is false, BUT ONLY if ExtraObject exists. That way, if I'm on the pages that don't have ExtraObject, there's no error.
I tried this:
if (MyValue === true &&
(typeof ExtraObject === undefined || ExtraObject.ExtraBool === false)) {...}
How should I rewrite this?
At the moment, I keep getting "ExtraObject is not defined error".
Thanks.
That should be:
typeof ExtraObject === "undefined"
typeof returns the type of the expression as a string, so you need to compare the name "undefined" to the result.
In my opinion, your condition is a bit too explicit. I'd go with something shorter:
if (MyValue && !(ExtraObject && ExtraObject.ExtraBool)) {...}
If you're communicating with your own GUI code, you can assume that the types are as expected. Type checking in JavaScript is rather cumbersome, so if you know what you're dealing with you can be less explicit. (This doesn't apply to user input though. Never trust user input.)
The logic is not quite correct:
if (MyValue && ExtraObject && !ExtraObject.ExtraBool) { ... }
I'm guessing that null would be a value ExtraObject shouldn't have either; that is, I presume that you r condition is really better stated that it should be a reference to an object.
Thus, the condition as I wrote it will be true when MyValue is "truthy", ExtraObject is a reference to a real object, and the property ExtraBool on that object is "falsy".
Sometimes it's necessary to make explicit comparisons to boolean constants, but in my opinion it's a code smell. (Of course, it can also be dangerous to just check truthiness/falsiness ...)
edit If your requirement is that the expression be true when MyValue is true and either ExtraObject is not a reference to an object or it's ExtraBool property is true, then I'd write that:
if (MyValue && (!ExtraObject || !ExtraObject.ExtraBool)) { ... }
Which is "better" is a matter of personal preference and experience.
Truth table time!
A is MyValue*
B is window.ExtraObject**
C is ExtraObject.ExtraBool
A B C | O
------+--
0 0 0 | 0
0 0 1 | 0
0 1 0 | n/a***
0 1 1 | 0
1 0 0 | 1
1 0 1 | n/a***
1 1 0 | 1
1 1 1 | 0
What we find with these values is that the simplest equation to produce O is:
A && !C
So your code should be:
if (MyValue && !ExtraObject.ExtraBool) {}
But of course, you mentioned not wanting to run into issues if ExtraObject wasn't defined:
var extraBool = window.ExtraObject ? ExtraObject.ExtraBool : false;
if (MyValue && !extraBool) {}
An alternative means of writing extraBool is:
var extraBool = window.ExtraObject && ExtraObject.ExtraBool;
You can then inline this:
if (MyValue && !(window.ExtraObject && ExtraObject.ExtraBool)) {}
An alternative of writing !(a && b) is !a || !b, which means that:
if (MyValue && (!window.ExtraObject || !ExtraObject.ExtraBool)) {}
is also correct.
* it could be MyValue===true depending on how strict you need to be
** alternatively typeof ExtraObject !== 'undefined'
*** it's not actually possible to have ExtraObject be undefined and access ExtraObject.ExtraBool
if ((MyValue === true) && (typeof ExtraObject === undefined || ExtraObject.ExtraBool === false)) {}

If condition checking for two TextFields Value

if(a.value === undefined || a.value.length>37 ||
b.value === undefined || b.value.length > 256) {
If the first one is undefined or greater than a length of 37. I get a error, but it does not check for the second field at all.
use parenthesis. It checks from left to right and stops once it hits a fail the way you have it set up.
Try
if((a.value === undefined || a.value.length>37) ||
(b.value === undefined || b.value.length > 256)) {
Conditional evaluation is lazy, i.e. it stops as soon as the result has been determined. That is, if (A && B) will not evaluate B if A is false, because the conjunction will have to be false already, and similarly if (A || B) will not evaluate B if A is true because the disjunction is already true.
You're forgetting what an OR in logic means. It only going to check until it finds one true statement.
Try regrouping:
((a.value === undefined || a.value.length>37)
||
(b.value === undefined || b.value.length > 256))
Just about elevating the condition a bit, and bringing a more broad result back instead of chasing the first true response.

Categories

Resources