I am making a project using ReactJS and I am using a statement, but I do not know the name of it.
Here is a bit of my code so it might make sense.
function Login(props) {
return (
<form>
<input
type="text"
placeholder="username"
onChange={e=>props.app.setState({"username":e.currentTarget.value})}
value={props.app.state.username}
/>
<input
type="password"
placeholder="password"
onChange={e=>props.app.setState({"password":e.currentTarget.value})}
value={props.app.state.password}
/>
<button type="button" onClick={_=>props.app.loadTasks()}>Login</button>
{props.app.state.logged_in == -1 && <p className="error">Incorrect username or password</p>}
{props.app.state.logged_in >= -1 && <title>Task Keeper</title>}
</form>
);
}
The exact thing I need a name for is this line here:
{props.app.state.logged_in == -1 && <p className="error">Incorrect username or password</p>}
{props.app.state.logged_in >= -1 && <title>Task Keeper</title>}
Like I am using them and I don't even know what they are called. And if possible explain how is working? I am only assuming is working like an if statement.
What you are looking for is called Short-circuit evaluation and is analyzed really good on the MDN web docs.
First of all, an explanation of how this works, because it can be quite confusing when you're starting. When you do:
{props.app.state.logged_in >= -1 && <title>Task Keeper</title>}
You're telling React to render the result of the following operation:
props.app.state.logged_in >= -1
AND
<title>Task Keeper</title>
The ending result is that if props.app.state.logged_in >= -1 is true, then
<title>Task Keeper</title>
is rendered, and if not, then nothing is rendered. That is similar to telling React:
if (props.app.state.logged_in >= -1)
<title>Task Keeper</title>
Now as to what to call that concept in general, I'd say it's just conditional rendering. It works that way because of a quirk in javascript:
&& evaluates as the left hand side if the left hand side is false, otherwise it evaluates as the right hand side. Meaning that true && expression is equal to expression, and false && expression is equal to false. In general, The value of the && expression is the value of the subexpression last evaluated. This way of doing things is called short circuit evaluation.
Related
I just saw this construction for the first time in javascript
if (someConditionIsMet && !(anotherCondition && oneMoreCondition)) {
return something
}
There is a !() inside of the if-conditional statement. I'm wondering what exactly that does. Is it just a way of grouping several conditions together and making sure they all evaluate a certain way before triggering logic? If so, is this merely to simplify the appearance or is there some logical advantage here?
Specifically for !(anotherCondition && oneMoreCondition), it means NOT (anotherCondition AND oneMoreCondition).
This is De Morgan's laws:
not (A and B) = not A or not B
Some might say that not A or not B is easier to read than not (A and B) but that's personal preference.
Expanding the whole condition using De Morgan's law would result in:
someConditionIsMet AND (NOT anotherCondition OR NOT oneMoreCondition)
in Javascript:
if (someConditionIsMet && (!anotherCondition || !oneMoreCondition))
You can use that expanded form if you think it's more readable.
!() In any case in javascript means that if they are NOT true. So basically like in this case...
if(!(anotherCondition && oneMoreCondition)) {
Console.log("If both set to false this would run!");
}
if anotherCondition and oneMoreCondition were both set to false this would actually return true. This here might help you: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT_!
It's evaluating the condition of anotherCondition && oneMoreCondition, and then reversing it.
So if the condition evaluates to true, the ! makes the condition evaluate to false.
I found the following in a code example at datatables.net.
return value > 20 ? true : false;
Why wouldn't they have just written
return value > 20;
Could the latter return values other than true or false? Trying to figure out whether they were maybe just thinking the code was more readable this way, or whether there is actually a significant reason for doing this that I'm not aware of.
The only possible result is true or false. I don't think it makes it more readable. The only reason they may have done it that I can think of is that they were a new developer and didn't realize value > 20 was valid to return.
This is along the same lines as someone writing this:
if(value > 20 === true){ . . . }
Which is unnecessary because if conditions are implicitly compared against their "truthy-ness". The statement should be:
if(value > 20){ . . . }
As such, in your example, the code should just be:
return value > 20;
Because (as you correctly surmize) a greater-than/less-than expression can only result in true or false.
Now, if someone wanted to return an alternate set of binary results, then you could see something like this being used:
return value > 20 ? "acceptable" : "unacceptable";
I'm trying to check if an input has been touched and is empty (without the built in functions in angular).
<form-input is-invalid-on="isTouched && !gs.data.name || gs.data.name.length > 50"></form-input>
If isTouched && !gs.data.name evaluates to true && false then that side of the expression becomes false
So my question is quite simple, how do I make the entire expression evaluate to true if the input has been touched and if it's empty or has a length greather than 50?
I believe it is used as attribute directive.
is-invalid-on="(isTouched && gs.data.name.length) || gs.data.name.length > 50"
Reason? I assumed your gs.data.name is a string. Empty string when evaluated in javascript is still a truthy value. So you must evaluate it to length.
<form-input is-invalid-on="(isTouched && !gs.data.name) || (gs.data.name.length > 50)"</form-input>
can try using () and also check gs.data like isTouched && (!gs.data || !gs.data.name || !gs.data.name.length || gs.data.name.length > 50)
<form-input is-invalid-on="isTouched && (!gs.data || !gs.data.name || !gs.data.name.length || gs.data.name.length > 50)"></form-input>
Angular expression does not work exactly the same than javascript from what i got try this one :
<form-input is-invalid-on="isTouched && gs.data.name.length==0 || gs.data.name.length > 50"></form-input>
Assuming you properly initialized gs.data.name to empty string.
By the way you forgot the > on your tag.
I finally found the reason as to why it was behaving so strange, and as this question has many answers I could not delete it. So I might as well explain what happened.
It turned out that isTouched was always undefined because I was using it outside of the directive (even if it was used in an attribute of the directive) which made the expression undefined && false, resulting in isInvalidOn always being false.
Instead I made it so that I used isTouched later in the actual form-input template as ng-class={invalid: isInvalidOn && isTouched}, resulting in the desired behavior.
I have a JavaScript calls structured this way:
if (($(this).scrollTop() == 0) && !controlsVisibility) {
triggerControls();
}
else if (currentScroll > (previousScroll + 100) && controlsVisibility) {
triggerControls();
};
While triggerControls() does just-in-case typecheck for undefined, and uses controlsVisibility as default arg determine what exactly it is supposed to do. I think:
Did I made a mistake of not passing controlsVisibility as a function arg inside if clause. If value of that variable changes between I call triggerControls() and function's execution (microsecond?) — should I:
account for the possible change by using the global state (as it is now)
or
interfere the change by passing stable args in advance?
I understand that this might be determined on case-by-case basis, but I would really appreciate some tips.
If the current implementation (1) is OK
I could've written both scenario checks in one if just by using || as I am executing the same function. Except for being messy and making the code largely unreadable why shouldn't I do just that?
If value of that variable changes between I call triggerControls() and function's execution (microsecond?)
No. While your script is executing, nothing else will change that variable - JavaScript is single-threaded. Unless triggerControls does something asynchronous and expects the value to be the same in a future turn of the event loop, everything is fine.
I could've written both scenario checks in one if just by using || as I am executing the same function. Except for being messy and making the code largely unreadable why shouldn't I do just that?
I don't see a reason not to do that. It's not messy to avoid repetition (but dry), and I wouln't consider it unreadable. You even might use the ternary operator to shorten (and optimise) it:
if (controlsVisibility
? currentScroll > (previousScroll + 100)
: $(this).scrollTop() == 0
) {
triggerControls();
}
I disagree with the statement that rolling the two conditions with an || operator is unreadable. With the right formatting it is very readable:
if (
(($(this).scrollTop() == 0) && !controlsVisibility) ||
(currentScroll > (previousScroll + 100) && controlsVisibility)
) {
triggerControls();
};
That's clearly two conditions switched by controlsVisibility. I personally would prefer controlsVisibility to be checked first to make the fact that it's a switch clearer:
if (
(controlsVisibility && currentScroll > (previousScroll + 100)) ||
(!controlsVisibility && ($(this).scrollTop() == 0))
) {
triggerControls();
};
However, you also asked if there is a more compact way to write this and there is:
if (controlsVisibility ?
currentScroll > (previousScroll + 100) :
$(this).scrollTop() == 0
) {
triggerControls();
};
I'd argue that the code above is obvious and readable but not everybody likes the ternary operator.
So I'm using a shorthand JavaScript if/else statement (I read somewhere they're called Ternary statements?)
this.dragHandle.hasClass('handle-low') ? direction = "left" : direction = "right"
This works great, but what if later I want to use just a shorthand if, without the else portion. Like:
direction == "right" ? slideOffset += $(".range-slide").width()
Is this possible at all?
you can use && operator - second operand expression is executed only if first is true
direction == "right" && slideOffset += $(".range-slide").width()
in my opinion if(conditon) expression is more readable than condition && expression
Don't think of it like a control-block (ie: an if-else or a switch).
It's not really meant for running code inside of it.
You can. It just gets very ugly, very fast, which defeats the purpose.
What you really want to use it for is ASSIGNING VALUES.
Taking your initial example and turning it on its head a little, you get:
direction = (this.dragHandle.hasClass("handle-low")) ? "left" : "right";
See. Now what I've done is I've taken something that would have required an if/else or a switch, which would have been used to assign to that one value, and I've cleaned it up nice and pretty.
You can even do an else-if type of ternary:
y = (x === 2) ? 1 : (x === 3) ? 2 : (x === 4) ? 7 : 1000;
You can also use it to fire code, if you'd like, but it gets really difficult after a while, to know what's going where (see the previous example to see how even assignment can start looking weird at a glance)...
((this.dragHandle.hasClass("...")) ? fireMe(something) : noMe(somethingElse));
...this will typically work.
But it's not really any prettier or more-useful than an if or a branching, immediately-invoking function (and non-JS programmers, or untrained JS programmers are going to crap themselves trying to maintain your code).
The conditional operator is not a shorthand for the if statement. It's an operator, not a statement.
If you use it, you should use it as an operator, not as a statement.
Just use a zero value for the third operand:
slideOffset += direction == "right" ? $(".range-slide").width() : 0;
What you have will not work, but why not just use a one line if statement instead.
if(direction == "right") slideOffset += $(".range-slide").width();
This involves less typing than the method Ray suggested. Of course his answer is valid if you really want to stick to that format.
No, This is not possible, because ternary operator requires, three operands with it.
first-operand ? second-operand (if first evaluates to true) : third-operand (if false)
you can use && operator
direction == "right" && slideOffset += $(".range-slide").width()
This doesn't exactly answer your question, but ternaries allow you to write less than you've shown:
direction = this.dragHandle.hasClass('handle-low') ? "left" : "right";
And now that I think about it, yeah, you can do your question too:
slideOffset + direction == "right" ? = $(".range-slide").width() : = 0;
This is a theory. The next time I have an opportunity to += a ternary I will try this. Let me know how it works!
You can use this shorthand:
if (condition) expression
If in some cases you really want to use the if shorthand. Even though it may not be the best option, it is possible like this.
condition ? fireMe() : ""
Looks weird, does work. Might come in handy in a framework like Vue where you can write this in a template.
You can using Short-circuit Evaluation Shorthand. if you want the if condition just write the else condition.
let
a = 2,
b = a !== 2 || 'ok';
console.log(b);