Why is the if conditional set to !false? - javascript

This is taken from another question of mine. Where the code below was given as an answer, though i'm not quite sure what is happening in it.
The aim is to only fetch userid once at the start instead of fetching it everytime fetchupdate() is called.
var delay = 300000, userIdFetched = false;
function GetUpdate(status)
{
if(status == "fail")
{
setTimeout(function(){
fetchupdate();
},delay * 2);<-- need to make this double itself
}
else
{
setTimeout(function(){
fetchupdate();
},delay);
}
};
function fetchupdate(){
var userid=$_SESSION['UserID'];
$.ajax()
{
type:"POST",
url:"getupdates.php",
data:{userid: userid},
complete:function(data,status)
{
if(status == true)
{
if(!userIdFetched){ <----Why is this set to !userIdFetched instead of userIdFetched
userIdFetched = true;
//Get the user Id here
}
$("#Updates").text(data);
GetUpdate("success");//Changed to String
}
else
{
$("#Updates").text("You have no updates.")
GetUpdate("fail");//Changed to String
}
}
}
}
Question:
Why is the if condition set to
if(!userIdFetched)
which evaluates to (!false) --> if(true), which causes the code in the if block to run, after which userIdFetched is set to true?
Shouldn't the if conditional be set to
if(userIdFetched)
which should cause the code in the if block to run, after which userIdFetched would be set to true, to represent the userid being fetched?
I would appreciate someone clarifying this up for me if possible.

No, it should be if(!userIdFetched), because you only need to enter the if-block when userIdFetched is false. If it's true, then there's no need to enter the if-block.
It might help to think of it as being roughly equivalent to:
if(userIdFetched == false)
Although there are some difference in how x == false and !x works with regard to some 'falsey' values (demonstration). In your case, since you're only dealing with Boolean values, this is not an issue.

Related

How to exit or break out from an else if

I've searched for a couple stackoverflow questions although couldn't find my answer.
I'm trying to break from an else if statement and was wondering if there was a more efficient way.
Heres a snippet:
var argument = "something";
if(argument == 'not_this'){
// this doesn't trigger
} else if(argument){
// this triggers although if the functions in here doesn't match what I want,
// how do I make It skip to the else statement without adding another else
// if statement?
} else {
// do something if both statements above fail
}
Is there something that I can do which exits from the else if(argument)... without adding another else statement? I've tried using switch and case although those don't seem to help.
Thanks.
You could set a flag that is by default true, and whenever the argument is valid you set it to false.
Then, to know when to execute the 'else' block, you can just check whether the flag is true or not:
var argument = "something";
let invalid = true
if (argument == 'not_this') {
// this doesn't trigger
invalid = false
} else if (argument) {
if (typeof argument != 'string') {
//valid
invalid = false
}
}
if (invalid) {
console.log('invalid')
}
Restructure the code to avoid confusing states, move out the if 'has value' check.
if (argument) {
if (argument === 'not_this') {
// this doesn't trigger
}
} else {
// do something if both statements above fail
}
For equality, it is safer to use strict equal === instead of loose equal ==
You could try using return; to break out of the statement, as that would stop all other code from being read.

Recursive Operation and then jump out of the loop

I have an object which stores department hierarchy. Each department might have sub department as well. I am trying to loop to check all department and also sub(child) department properties are Open.
However, whenever I hit recursive call, it only iterates once and jump directly to return true, even though there are still some items which has not checked in the loop yet.
validateDepartment(departmentHierarchy: any) {
for (let dept of departmentHierarchy.children) {
if (dept!= undefined && dept!= null) {
if (dept.instance.status == "Open")
{
continue
}
else
{
if (dept.children != undefined && dept.children != null) {
this.validateDepartment(dept);
}
else {
return false
}
}
}
}
return true
}
Not part of any answer, but it helps to only write the code that "does" things, rather than having lots of code that does "what the code would already do anyway", such as calling a continue when the iteration code is a single if/else. We can rewrite your code to this, and have something easier to work with:
validateDepartment(tree: any) {
// step 1: do any validation of the top node
if (!validateTopNodeOnly(tree)) {
// this is a stop condition.
return false;
}
if (!tree.children) {
// this is also a stop condition, but for a different reason.
// a department without children should not _necessarily_ be invalid.
return true? return false? probably return true since the node itself is fine.
}
if (tree.instance && tree.instance.status !== "open") {
// and this is a third condition, but for yet another reason.
// I'm guessing this is also not "invalid", just means we shouldn't recurse.
return true? return false? probably return true as well.
}
// Then, get all (non-falsey) children,
let children = tree.children.filter(e => e);
// and iterate over them:
for (let e of children) {
let result = this.validateDepartment(e);
// cut your run short if validation fails
if (result === false) {
return false;
}
}
// and this is the expected stop condition for a normal run.
return true;
}
But using true/false is incredibly naive and won't tell you anything about where validation failed, so you'll want to work in "what failed", typically by returning a reference to the actual "thing that's getting validated" so that if your function returns true, all is well, and it returns something !== true then you know it failed, and the thing it returned is the department where things went wrong.
Also note that by using an early return on validation failure, you're missing out on information: instead it's way better to use .map() and construct a running tally of all deparments that pass/fail validation, so that you return an array in which either result.every(e => (e===true)) is true, or is false, in which case result.filter(e => (e!==true)) gives you the set of every single failed department.
isopen = this.validateDepartment(this.departmentHierarchy);
validateDepartment(dept: any): boolean {
let result=(dept.instance.status == "Open");
if (result) {
if (dept.children) {
dept.children.forEach(x => {
result = result && this.validateDepartment(x)
})
}
}
return result;
}

If a is false, then does if(a) === if(false)?

I am working on a JavaScript exercise on an interactive website, and I just really need some assistance in understanding the logic behind this...
The exercise asks that you define a variable programming, and set it equal to false.
var programming = false;
Then, if programming equals false, a function, happy is to return true.
programming has already been set to false, so my first thought was to just write:
if (programming) {
// this
I made the mistake of not using the ! operator, which is what they were requesting, so I then tried to write:
if (!!programming) {
// this
To me, this says: not not false which I thought would cancel out and equal false
But I get the following error:
Oops, try again. It looks like your happy function returns true instead of false when programming is true
this works:
if (!programming) {
// this
I'm just not understanding why (!programming) evaluates to false, when I believe this is basically saying: (!false)
Please help me understand the error of my ways. Thank you.
For a reference, here is my full code:
var programming = false;
var happy = function() {
if (!programming) {
return true;
} else {
return false;
};
};
Edit:
I've found the solution. zystvan explains it on this post: https://discuss.codecademy.com/t/why-is-this/42458
I'm just not understanding why (!programming) evaluates to false, when I believe this is basically saying: (!false)
This syntax:
if (!programming) {
}
Is essentially shortform for:
if (programming != true) {
}
Which is another way of writing:
if (programming == false) {
}
I think not understanding this is the source of your confusion.
Additionally take note of the following:
var programming = true;
programming; // true
!programming; // false
!!programming; // true
programming = false;
programming; // false
!programming; // true
!!programming; // false
So your program could be shortened to:
var programming = false;
var happy = function() {
return !programming; // returns true when programming is false
};
if (programming) does not mean "if programming is set to false", it's actually the opposite ! The syntax of a simple if block is the following :
if (condition) { action }
And it is executed in the following way :
if condition evaluates to true, then execute the action
The exercise asks you to execute the action only if programming is false. "programming is false" is your condition here. You know it's currently true, so you could as well write if (true) { action } or simply action, but your exercise would probably consider this cheating (usually the condition won't be so obvious).
So what you need is to produce a condition that will evaluate to true if and only if programming is false. You could use a comparison operator == or !=, or the negation operator ! your exercise hints at.
EDIT: The image you have just posted contains different code from the code pasted into your question. Your question used !programming but your image shows !!programming. Change it to !programming (as per your question) and it should be fine.
I think your program is correct - are you sure you executed it correctly and are you sure that the test is correct?
Pasting your code into node gives the following ...
> var programming = false;
> var happy = function() {
... if (!programming) {
..... return true;
..... } else {
..... return false;
..... };
... };
> happy();
true
> programming = true; happy();
false
> programming = undefined; happy();
true
> programming = null; happy();
true
... so when programming is true your code returns false which is the desired result and contrary to the test result?
Oops, try again. It looks like your happy function returns true instead of false when programming is true
You could shorten your function BTW to:
var happy = function() { return !programming; }
And finally beware the comments above that
!programming
is equivalent to
programming != true
This is not necessarily true if programming has a non-boolean value!! Consider for example the following:
> programming = 5;
5
> !programming
false
> programming != true;
true
or better still
> var sad = function(value) { return (!value) === (value != true) }
> sad(undefined)
true
> sad(null)
true
> sad(false)
true
> sad(true)
true
> sad(1)
true
> sad(2)
false
> sad("")
true
> sad("A")
false
When you use:
if (!someVariable) {
}
it is saying "if the value of someVariable is not truthy (any value other than null, undefined, or false"), then execute the body of this "if".
So, when you do this:
var someVariable = false;
if (!someVariable) {
//Since someVariable is not truthy, this will run
}
var programming = false;
var happy = function() {
if (!programming) {
return true;
} else {
return false;
};
};
is the same as
var programming = false;
var happy = function() {
if (programming != true) {
return true;
} else {
return false;
};
};
So you have two cases
programming = true
if (true != true) => is not true => else block is called => false is returned
programming = false
if (false != true) => is true => if block is called => true is returned
I think you may have more semicolons that cause conflict in execution time, so if the function doesnt execute right the variable is set to null and you get a False in return.
Try to just remove the second semicolon, like:
var programming = false;
var happy = function() {
if (!programming) {
return true;
} else {
return false;
}
};
'true' or 'false' is sometimes confusing even for an experienced programmer.
Instead of counting 'true' or 'false', treat them as 'success' and 'fail'. An expression can be 'success' or 'fail'.
if(expression){
I'll be only executed when 'expression' is a success exp.
}
So when you write
var programming = false;
if(programming){}
programming is a fail expression, so anything in the 'if' won'be executed.
...if statements execute the following block of code if the statement in the parens evaluates as true/truthy.
Everything you write is, for some reason, on the assumption that since your var is false it should pass the if statement. I have no idea where you'd get that idea from.
So yeah, if (programming) where programming is false will not execute the code in the if statement that follows.
And likewise, you're right that !! will just flip it twice, back to a boolean of whatever it originally was (truthy to true or falsey to false)...and it was originally false...so yeah, again, the if statement would not pass and not execute the code.
! flips the false value to true, which makes it pass the if statement. So yeah, if you want a variable to pass an if statement if the value is false, then if (!programming) is exactly what you'd do. It's not evaluating to false...it's evaluating to true, which is why it then passes the if statement.

cancelling alert poppup in javascript

Consider this code:
function reason(id) {
var reason = prompt("State reason");
while (!reason.trim()) {
reason = prompt("Please enter text");
}
document.getElementById(id).value = reason;
return true;
}
It works perfectly fine, but when I want to get rid of the poppup by pressing escape for example, the function returns true because the form executes. What should I do to make it do nothing if I close/cancel the poppup?
... the function returns true because the form executes. What should I do to make it do nothing if I close/cancel the poppup?
It depends entirely on how you call your reason function, but if you want reason to return false when prompt is cancelled, then:
function reason(id) {
var reason = prompt("State reason");
while (reason !== null && !reason.trim()) { // *** Changed
reason = prompt("Please enter text");
}
if (reason === null) { // *** Added
return false; // *** Added
} // *** Added
document.getElementById(id).value = reason;
return true;
}
prompt returns null when you cancel it.
But again, it's up to what calls reason to do something appropriate with the true or false.
Side note: You can call your function and a variable inside it by the same name, but it's not a great idea. If it's a habit, you'll end up making writing recursive functions quite difficult...

Check both conditions in an if statement even if the first one is false

I have two statements in an if block that both link to a function that will return a bool. Both statements must be true for the code to run but I want them both to be checked even if the first one is false. The relevant code:
if (myFunc(one) && myFunc(two)) {
//execute
}
myFunc will execute some code before returning false, but this code is not executed on two if one returns false.
I got this to work, but it feels like a hack:
if ((myFunc(one) && myFunc(two)) || (myFunc(two) && myFunc(one))) {
//execute
}
Does anyone have a better solution? Thanks!
Another way:
var first = myFunc(one),
second = myFunc(two);
if (first && second) {
//execute
}
In this case both will be executed first and checked for non false values later.
use the & operator
take a look at this example
function a (){
console.log(1);
return true;
}
function b (){
console.log(2);
return false;
}
if(b() & a() == true){
console.log('asas');
}

Categories