Javascript IF loop takes false and execute the true loop with jquery - javascript

Here is jquery code in rails app. The purpose of the code is to eval the value of #rfq_need_report and show the #rfq_report_language if need_report is true or hide if false:
$(document).ready(function() {
var rpt = $('#rfq_need_report').val();
alert(rpt);
if (rpt) {
alert(rpt);
$('#rfq_report_language').show();
alert('show');
} else {
$('#rfq_report_language').hide();
alert(rpt);
alert('hide');
}
}); // end ready
The alert here is just for debug. The rpt is false, however alert('show') gets executed. It seems that the if loop is taking false and decided to execute the loop for true. Sometime If loop is working and sometime it does not. What could cause this strange behavior? Thanks.

In HTML the value field of any input like value="something" is always evaluated as a string. My guess is that in javascript you either set that value to true or false but it is in fact set as "true" or "false" as strings. You could try what was answered on this topic : How can I convert a string to boolean in JavaScript?

rpt could be a string, therefore converting it into a boolean will help:
if(rpt === "false") { rpt = false; } else { rpt = true; }

I have to assume that $('#rfq_need_report').val() is not passing back an actual boolean value, but something that JavaScript considers 'truthy', which is why your if statement executes the truth clause.
There are two quick methods (that I use) to convert 'truthy' values to an actual boolean:
1: var bool = !!truthy;
2: var bool = truthy === 'true'
I use the second when expecting a string value, and the first when not expecting a string.
The first example may need an explanation, so...
The first ! "nots" the truthy value to an actual boolean, albeit the opposite of what I wanted, the second "nots" it right back to where it should be.
For more examples of truthy vs falsy, simply pop javascript truthy falsy into your favorite search engine and start reading. My personal quick reference is: Truthy and falsy in JavaScript

Related

Shortened if statements and their direct equivalents in JavaScript

I've been studying JavaScript for a couple months, and I have some questions.
Say we have some if statements like this:
if (something)
if (!something)
From what I have looked up, the first statement checks whether something evaluates to true, whereas the second one checks for whether the condition is not true(I recall reading the ! coerces it into boolean and then 'inverses' it).
However, I'd like to know what are these statements' direct equivalents when not "shortened". I'd like to understand code like this more in depth before really using it.
Is if (something) the same as if (something == true)? Or even if (something === true)?
And what would be the "non-shortened" (for my lack of a better term) direct equivalent of if (!something)?
Thank you for any help.
Part 1:
When we use if(something) javascript will check if it is a 'Truthy' or 'Falsy' value.
So if we say
if(1) {
alert("Yes, it's true...");
}
javscript will check if 1 is a "truthy" value and it is.
Everything that is not a falsy value is truthy by extension.
Falsy values are:
0, 0n, null, undefined, false, NaN, and the empty string “”.
So if we directly put any of the above into a parenthesis it will return false.
e.g. if (null) ... the if clause won't be executed because null is falsy.
Part 2:
When we use if(something == true), we check if one value is equal to another value. If the types are not the same, since we're using == coercion will happen.
What is this about 'coercion'?
If we say if('1' == 1) this will execute the if clause as it returns true. Javascript will convert 1(number) to '1'(string) in this case.
If we want to be strict and say "I only want true if they're both numbers, I don't care if 1 is a string" then we use
if(1 === '1') and this will not execute the if clause(because the condition returns false).
So if we say if(false == false) this will return true because false is equal to false, and the if clause will be executed.
Note the difference if we said if(false) or if('') the if statement will not be executed.
Next, if we want to use negation, we have to put the ! in front of the boolean we're negating, regardless of whether it's part of an if condition or... There is no way around it.
However, there is a shorter version of this:
var a = 3;
var b = 2;
if(a===b) {
alert('A is equal to B');
} else {
alert('B is not equal to A');
}
This is considered shorter(ternary operator):
Note that if we want to use more than one statement, we should use the if else
a = 3;
b = 2;
a===b ? alert('A is equal to B') : alert('B is not equal to A');

Difference between equality checking inside 'if condition' vs 'console.log' [duplicate]

This question already has answers here:
Empty arrays seem to equal true and false at the same time
(10 answers)
Closed 4 years ago.
I was trying out a code snippet and the results are different for an empty array check inside a console.log statement and in a conditional statement.
Help/Thoughts on why this is different?
Thanks in advance!
//Output: true
if([]) {
console.log(true)
} else{
console.log(false)
}
//Output: false
console.log([] == true)
You seem to be running into a known JavaScript quirk.
"[] is truthy, but not true"
The problem isn't where you are doing the evaluations, but rather that the two evaluations which seem identical are actually different.
See
https://github.com/denysdovhan/wtfjs#-is-truthy-but-not-true
My assumption is that the if/else block, in part of its "truthful" test is checking if something exists (not just if it is true or not) -- wherein the straight console print is comparing the value of the empty array against a boolean (which would be false)
let test = 'apple';
if( test ){
console.log( 'if/else: ' + true );
}else{
console.log( 'if/else: ' + false );
}
console.log( 'log: ' + ( test == true ) );
The two snippets are actually doing different things, hence the different results.
The first, with [] as the condition of the if statement, coerces the array to a Boolean value. (if, naturally enough, only works on Booleans, and JS will happily convert the given value if it isn't already Boolean.) This produces true - all objects in JS are "truthy", which includes all arrays.
For the second snippet, you are using the "loose equality" operator == - for which the JS specification provides a set of rules for how to convert the values into other types, eventually reaching a straightforward comparison between two values of the same type. You might want, or hope, that comparing a non-Boolean to true or false in this situation coerced the non-Boolean to Boolean - but this isn't what happens. What the specification says is that first the Boolean is coerced to number value - resulting in 1 for true (and 0 for false). So it reduces to [] == 1 - which will go through a few more conversions before resulting in a false result.
The key point is that no conversion to Boolean happens in the second case. If you think this is stupid, you're probably right. This is a bit of a gotcha, and one of the reasons many guides tell you never to use == in JS. I don't actually agree with that advice in general (and hate linters telling me to always use === in any circumstances) - but you do have to be aware of some dangers. And using == to compare a value to true or false is something to always avoid.
Luckily, if you want to test if x is truthy or falsy, you have a very short and understandable way to do it - the one you used in the first snippet here: if (x)
[edit] So my original answer was confusing as heck, and there are some incongruencies in the many answers you find on this subject all over the internet; so, let me try this again:
Part 1: Why they are Different
if([]) and if([] == true) are not the same operation. If you see the below example, you will get the same result when doing the same operation.
//Output: false
if([] == true) {
console.log(true);
} else{
console.log(false);
}
//Output: false
console.log([] == true);
Part 2: Why it matters AKA: the confusing bits
In JS, the following is a common expression used to see if an object/variable exists:
var foo = "Hello World";
if (foo) ...
From a design perspective, this test is not important to see if foo is equal to true or false, it is a test to see if the program can find the object or variable foo. If it finds foo, then it executes the results in the "then" condition, otherwise you get the "else" condition. So, in this case, it will convert foo to either false for does not exist, or true for does exist. So in this case the string is reduced to a boolean.
In contrast:
var foo = "Hello World";
if (foo == true) ...
Is typically trying to find out if the value of foo actually equals true. In this case, you are comparing the value of foo "Hello World" to a boolean, so in this case, "Hello World" does not equal true.
Just like foo, [] can be evaluated more than one way. An empty array is still an object; so, in the first case, it coerces to true because it wants to know if [] can be found; however, [] also equals ['']. So now picture this:
if (['bar'] == 'bar') ...
In this case, JS will not look at ['bar'] to see if it is there, but as an object containing a single value which it can convert to the string, 'bar'.
So:
if([]); // is true because it is an object test that evaluates as (1 === 1)
and
if([] == true) // is false because it is a string test that evaluates as ('' == 1) to (0 === 1)

Calling a JavaScript function that returns a Boolean

* EDITED *
REF: Calling a JavaScript function that returns a Boolean [on hold]
function booleanFunction()
{
if (something) return true;
else return false;
}
My original question was "When calling a Boolean Function, is it correct to say?":
if (booleanFunction)
or
if (booleanFunction())
I had previously read that the first choice was correct. Your voluminous responses said otherwise.
Based on all that I have learned from all your responses, I conclude:
(1) if (booleanFunction) is truthy in the sense that this if statement will ALWAYS return true. In other words, this if statement is equivalent to asking if this booleanFunction EXISTS, independent of its correctness.
(2) to evaluate the value (true or false) returned by the booleanFunction, I need to say if (booleanFunction()).
Have I concluded correctly?
The text you quote is outright incorrect.
To call a function, use parentheses. If the function takes no arguments, the call looks like booleanFunction() and returns a value.
To evaluate a value, put it into parentheses. In an if-statement, while-loop, a value is converted to a boolean automatically, the same as (new Boolean( SOME_VALUE )).valueOf() or !! (SOME_VALUE). Refer to MDN for the full conversion rules. For instance,
if (booleanFunction()) {
is perfectly fine, but
if (booleanFunction) {
would convert the value of booleanFunction to boolean, and that is true, because any function object will be converted to true.
I have edited my original question. Hopefully, it is now totally clear.

JavaScript IF statement boolean strict

I am setting a mode in a script by passing a "truthy" boolean to a function. In the function a simple if statement checks if the param is true or false. I sometimes pass it as a string or a bool which has always worked, but for some reason it isn't for this:
setMode: function(Setting) {
if (Setting) {
console.log('Enabling mode');
} else {
console.log('Disabling mode');
}
}
For example when I pass it a string 'false' and log Setting to console, the console says false, yet the if statement thinks it's true.
I have to add this to the start of the function for it to work:
if (typeof Setting == 'string') {
Setting = (Setting == "true");
}
An example of it in use:
var inverted = $('INPUT[name="Mode"]').prop('checked');
app.setMode(inverted);
and another:
var mode = localStorage.getItem('Mode');
this.setMode(mode);
It's so bizarre since I've done this type of thing for years yet it's only starting now. Maybe because I'm using localStorage and .prop?
If you try to log 'false' it is obvious that console logs false(it is a string) and that the if statement sees true, because a not-empty string is a true boolean value.
If you want to check if the string is "true" or "false" you have to do it with normal operators. So you could add this line at the beginning of your function:
Setting = (typeof Setting === 'string') ? Setting === "true" : Setting;
To answer your question about string to boolean conversions:
ECMA SPEC:
The result [of this conversion] is false if the argument is the empty String (its length is zero);
otherwise the result is true.
So yes, if you pass the string "false" it will be converted to true, which means the only option you have is to manually check for the strings "true" or "false" and do the conversion by yourself.
However, the jQuery function .prop("checked") is supposed to return a boolean value (or undefined if the property is not defined). So I would say you should be able to actually do
if (elem.prop("checked"))
like here.
For example when I pass it a string 'false' and log it to console, the console says false, yet the if statement thinks it's true.
The console output is confusing, it is concealing the quotes and logging false both for the string "false" and the boolean false. Yet, these two are not equivalent, the string is not empty and indeed truthy.
Maybe because I'm using localStorage and .prop?
Yes. The .checked property returns a boolean and everything works well. In contrast, local storage only stores strings, and when you pass in a boolean you get back its stringification. You can undo that by using
var modeStr = localStorage.getItem('Mode');
var mode = JSON.parse(modeStr);
this.setMode(mode);

Can someone explain this 'double negative' trick? [duplicate]

This question already has answers here:
What is the !! (not not) operator in JavaScript?
(42 answers)
Closed 8 years ago.
I am by no means an expert at Javascript, but I have been reading Mark Pilgrim's "Dive into HTML5" webpage and he mentioned something that I would like a better understanding of.
He states:
Finally, you use the double-negative trick to force the result to a Boolean value (true or false).
function supports_canvas() {
return !!document.createElement('canvas').getContext;
}
If anyone can explain this a little better I would appreciate it!
A logical NOT operator ! converts a value to a boolean that is the opposite of its logical value.
The second ! converts the previous boolean result back to the boolean representation of its original logical value.
From these docs for the Logical NOT operator:
Returns false if its single operand can be converted to true; otherwise, returns true.
So if getContext gives you a "falsey" value, the !! will make it return the boolean value false. Otherwise it will return true.
The "falsey" values are:
false
NaN
undefined
null
"" (empty string)
0
Javascript has a confusing set of rules for what is considered "true" and "false" when placed in a context where a Boolean is expected. But the logical-NOT operator, !, always produces a proper Boolean value (one of the constants true and false). By chaining two of them, the idiom !!expression produces a proper Boolean with the same truthiness as the original expression.
Why would you bother? Because it makes functions like the one you show more predictable. If it didn't have the double negative in there, it might return undefined, a Function object, or something not entirely unlike a Function object. If the caller of this function does something weird with the return value, the overall code might misbehave ("weird" here means "anything but an operation that enforces Boolean context"). The double-negative idiom prevents this.
In javascript, using the "bang" operator (!) will return true if the given value is true, 1, not null, etc. It will return false if the value is undefined, null, 0, or an empty string.
So the bang operator will always return a boolean value, but it will represent the opposite value of what you began with. If you take the result of that operation and "bang" it again, you can reverse it again, but still end up with a boolean (and not undefined, null, etc).
Using the bang twice will take a value that could have been undefined, null, etc, and make it just plain false. It will take a value that could have been 1, "true", etc. and make it just plain true.
The code could have been written:
var context = document.createElement('canvas').getContext;
var contextDoesNotExist = !context;
var contextExists = !contextDoesNotExist;
return contextExists;
Using !!variable gives you a guarantee of typecast to boolean.
To give you a simple example:
"" == false (is true)
"" === false (is false)
!!"" == false (is true)
!!"" === false (is true)
But it doesn't make sense to use if you are doing something like:
var a = ""; // or a = null; or a = undefined ...
if(!!a){
...
The if will cast it to boolean so there is no need to make the implicit double negative cast.
! casts "something"/"anything" to a boolean.
!! gives the original boolean value back (and guarantees the expression is a boolean now, regardless to what is was before)
The first ! coerces the variable to a boolean type and inverts it. The second ! inverts it again (giving you the original (correct) boolean value for whatever you are checking).
For clarity you would be better off using
return Boolean(....);
document.createElement('canvas').getContext may evaluate to either undefined or an object reference. !undefined yields true, ![some_object] yields false. This is almost what we need, just inverted. So !! serves to convert undefined to false and an object reference to true.
It's to do with JavaScript's weak typing. document.createElement('canvas').getContext is a function object. By prepending a single ! it evaluates it as a boolean expression and flips the answer around. By prepending another !, it flips the answer back. The end result is that the function evaluates it as a boolean expression, but returns an actual boolean result rather than the function object itself. Prepending !! is a quick and dirty way to typecast an expression to a boolean type.
If document.createElement('canvas').getContext isn't undefined or null, it will return true. Otherwise it will return false.

Categories