I'm trying to write something like this with a ternary operator (needed because of jsx syntax constraints)
if(!this.state.msg) {
if(this.state.ask.length != 0) {
// do stuff
} else {
// do stuff
}
if(this....) {
//do stuff
} else {
// ...
}
} else {
//nothing
}
So I tried this dumb
!this.state.msg ? this.state.ask.length != 0 ? //do stuff : "" this.state... ? //do stuff : //do other stuff : //nothing
But it's obviously not the right way to go.
Any help very welcomed. thanks in advance.
Your true branch has two components; you can separate them with commas (parenthesized, since the comma has weaker associativity than the ternary operator). So
!this.state.msg ?
(
this.state.ask.length != 0 ? /*stuff*/ : /*stuff*/,
this... ? /* stuff */ : /* ... */
) : /* nothing */
Or, since the else branch is doing "nothing", you could replace the ternary operator at the top level with a simple and:
!this.state.msg &&
(
this.state.ask.length != 0 ? /*stuff*/ : /*stuff*/,
this... ? /* stuff */ : /* ... */
)
You are wrong in your assertion that JSX limits you in this way - read this doc page and you will see that you can use something like this:
{(() => {
// My awesome multi-step code
})()}
Maybe it'd help to add another perspective. It's very rare that you would actually need to use the ternary operator with JSX. In this case, I would consider moving all of this logic out into a separate function.
helperFunction: function() {
if(!this.state.msg) {
if(this.state.ask.length != 0) {
// return stuff
} else {
// return stuff
}
if(this....) {
// return stuff
} else {
// ...
}
} else {
// nothing
}
}
Then you'd be able to use your helper function from inside your render method.
React.createClass({
helperFunction: function() {
// ...
},
render: function() {
return (
<div>
{this.helperFunction()}
</div>
);
}
});
Your helper function can return values that can be used for attributes, or it can return other JSX components. Often I find it helpful to move code out of patterns that look like this:
render: function() {
return (
condition === 'example' ?
<MyComponent attr={this.props.example} onChange={this.props.onChange} /> :
<MyOtherComponent attr={this.state.example} onChange={this.state.onChange}/>
);
}
To code that looks like this:
helper: function(condition) {
if(condition === 'example') {
return (
<MyComponent attr={this.props.example} onChange={this.props.onChange} />
);
}
else {
return (
<MyOtherComponent attr={this.state.example} onChange={this.state.onChange}/>
);
}
},
render: function() {
return this.helper(condition);
}
Or even better in the case of string equality checking.
helper: function(condition) {
const default = <MyOtherComponent attr={this.state.example} onChange={this.state.onChange}/>
const conditions = {
example: <MyComponent attr={this.props.example} onChange={this.props.onChange} />,
example2: <MyComponent attr={this.props.example} onChange={this.props.onChange} />,
example3: <MyComponent attr={this.props.example} onChange={this.props.onChange} />,
};
return conditions[condition] || default;
},
render: function() {
return this.helper(condition);
}
This way gives you most of the power of a switch statement, but terser syntax too, it lets you elegantly select from a large number of conditional components. The same code written with if statements (regular or ternary) would be much more verbose.
For verbosity, clarity of expression and maintainability, I would not recommend converting if-else to ternary expression. Try to keep your code simple even at the expense of few extra lines.
Here it is if you just want to learn
!this.state.msg ?
(this.state.ask.length != 0 ? //do if stuff : //do else stuff),
(this.some == 0 ? //do 2nd if stuff : //do 2nd else stuff)
:
Visualizing it helps.
!this.state.msg ?
? this.state.ask.length != 0)
// do stuff
:
// do stuff
:
this.... ?
//do stuff
:
// ...
Related
I want to shorten the conditions of a javascript if but I don't know how I can achieve it
code:
if ((!emailValidation() || (!nameValidation()) || (!surnameValidation()) || (!addressValidation()) || (!cityValidation()) || (!postalCodeValidation()))) {
}
I have the conditions defined in this way:
let surnameValidation = () => {
if (apellidoUsuario.value.length == 0) {
surnameError();
return false;
}
else if (apellidoUsuario.value.length == 1) {
surnameError();
return false;
}
else {
apellidoUsuario.focus;
apellidoUsuario.style.border = '0';
apellidoUsuario.style.backgroundColor = 'transparent';
apellidoUsuario.style.outline = '1px solid #00ffb1'
apellidoUsuario.style.transitionDuration = '0.4s'
return true;
}
I appreciate any help! :)
You can remove all unnecessary parenthesis in your if condition:
if (
!emailValidation() ||
!nameValidation() ||
!surnameValidation() ||
!addressValidation() ||
!cityValidation() ||
!postalCodeValidation()
) {
}
Other than that, there's not really a clean, readable way to shorten your code.
Proposition #1:
I would probably get those validations into a variable or function:
validations() {
return [
emailValidation(),
nameValidation(),
surnameValidation(),
addressValidation(),
cityValidation(),
postalCodeValidation()];
}
and then I would:
if(validations().some(x=> !x)){
...
}
since validations return an array you can just use the some operator to find any invalid value.
Proposition #2:
I particularly would:
valid() {
return [
emailValidation(),
nameValidation(),
surnameValidation(),
addressValidation(),
cityValidation(),
postalCodeValidation()].every(x => x === true);
}
and then I would:
if(!valid()){
...
}
It is always cleaner to use true conditions on if statements instead of false ones.
References: Clean Code - Uncle Bob.
$scope.vergleich = function () {
if ($scope.relrechtsform.indexOf(dataService.dic.alt.rechtsformKanlei || dataService.dic.neu.rechtsformKanlei ) !== -1) {
return true
} else {
return false; }
}
}
I am currently student and intelliJ tells me I have to simplify this if-statement but I have no idea how. Maybe somebody can help me.
The simplification is probably that, if condition is a boolean, :
if (condition) {
return true;
}
else {
return false;
}
is equivalent to
return condition;
However there also seems to be a logical error in your test.
$scope.relrechtsform.indexOf(dataService.dic.alt.rechtsformKanlei ||
dataService.dic.neu.rechtsformKanlei ) !== -1
Does not mean the same thing as :
$scope.relrechtsform.indexOf(dataService.dic.alt.rechtsformKanlei) !== -1 ||
$scope.relrechtsform.indexOf(dataService.dic.neu.rechtsformKanlei) !== -1
Maybe you're looking for this:
$scope.vergleich = function () {
return $scope.relrechtsform.indexOf(dataService.dic.alt.rechtsformKanlei || dataService.dic.neu.rechtsformKanlei ) !== -1;
};
Tân's version is a correct answer to your question. However, with recent JavaScript you can simplify even more thanks to array.includes:
$scope.vergleich = () =>
$scope.relrechtsform.includes(dataService.dic.alt.rechtsformKanlei || dataService.dic.neu.rechtsformKanlei)
You can just use your condition instead of using IF else statement -:
$scope.vergleich = function () {
return ($scope.relrechtsform.indexOf(dataService.dic.alt.rechtsformKanlei ||
dataService.dic.neu.rechtsformKanlei ) !== -1);
};
This is a very basic issue about if statements. It doesn’t necessarily effect only javascript.
If object.user is undefined this will break:
if ( object.user.name ) {
sayMyName();
} else {
object.user = {};
object.user.name = 'Jane Doe';
sayMyName();
}
because it can not read a property of undefined. So i put the else stuff in a function and folded the if into another if:
function anonymous(object) {
object.user = {};
object.user.name = 'Jane Doe';
sayMyName();
}
if ( object.user ) {
if ( object.user.name ) {
sayMyName();
} else {
anonymous();
}
} else {
anonymous();
}
But this looks like bad code to me. This case must be a common problem. Or at least i have it quite often. Is there any good solution for this?
EDIT:
#Mritunjay's proposal
if(object && object.user && object.user.name){...}
is way better, but it doesn’t seem to be the best solution. Imagine a if-statements that tries to get obj.some.very.very.deep.property. I‘m currently trying to write a helper-function like checkPropertySafely(object.user.name); that goes back to object, and checks every property recursively, no matter how deep it is. So basically i try to automate #Mritunjay’s manually written statement.
I use bellow in this situation
if(object.user && object.user.name){...}
BTW you should check if object also exists.
if(object && object.user && object.user.name){...}
I finally figured out how to write the helper-function. Here it is:
function propertyExists(property) {
var statement = '';
var prevItem = '';
property.split(".").forEach(function(item, index) {
if (index != 0) {statement += ' && '}
statement += prevItem+item;
prevItem += item+'.';
});
return eval(statement);
}
With this function, i can now simply do this:
if ( propertyExists('object.user.name') ) {
sayMyName();
} else {
anonymous();
}
I have written an else / if statement in my plugin but for optimization (less code) I want it to be shorter.
if ( self.first() ) {
if ( self.second() ) {
self.run();
}
else {
self.other_run();
}
}
else {
return false;
}
Example
if ( check cookie is true ) {
if ( check timezone is true ) {
run sth
}
else {
run other thing
}
}
else {
do nothing
}
What about?
if ( self.first() ) {
self.second ? self.run() : self.other_run();
}
else {
return false;
}
Is it ok to write it like that?
return self.first() ? ( self.second() ? self.run() : self.other_run() ) : false;
self.first() ? ( self.second() ? self.run() : self.other_run() ) : false;
Should work fine, but I'm not sure why you'd want to obfuscate your code like that.
(Keep in mind that "shorter" code isn't always "better" code.)
That may work, with some explicit parenthesis to separate your wrapped statements. Though it's not really easier to read/understand. How about something like this?:
if (self.first() && self.second()) {
self.run();
return;
}
if (self.first()) {
self.other_run();
return;
}
return false;
This follows Martin Fowler's refactoring pattern called Replace Nested Conditional With Guard Clauses.
This also makes it more clear that your function isn't always returning a boolean value. (Something I didn't immediately notice until I wrote this.) Perhaps you mean to do so (a bug which wasn't noticed in the overly-brief version of the code)?:
if (self.first() && self.second()) {
self.run();
return true;
}
if (self.first()) {
self.other_run();
return true;
}
return false;
Naturally, this code is obviously fake just to demonstrate a point. But if the conditional clauses do start to get unwieldy, you can always extract them into their own functions:
if (somethingIsTrue()) {
self.run();
return true;
}
if (somethingElseIsTrue()) {
self.other_run();
return true;
}
return false;
I'm concerned my if condition is not correctly formatted.
Does this look right to you?
function validateCoupon( form ){
if (form.textCoupon.value.length ){
if (form.textCoupon.value.toLowerCase() == "Item01") {
_gaq.push(['_trackEvent', 'Coupon', 'Activated', 'Item01']);
}
if (form.textCoupon.value.toLowerCase() == "Item02") {
_gaq.push(['_trackEvent', 'Coupon', 'Activated', 'Item02']);
}
$.get( "/include/checkCoupon.php", { coupon: form.textCoupon.value }, validateShipping );
}
else {
form.textCoupon.style.border = '';
validateShipping( "yes" );
}
return false;
}
Well, something appears to be a redundancy: form.textCoupon.value could be Item01 or Item02. If it's one it couldn't be the other, so I'd suggest you a switch statement.
Another problem is if you call .toLowerCase() this never will return Item01 but item01, and string equality is case-sensitive. Either call this function to both parts of condition or just don't use it.
If this were my code, this would be how I wrote it:
var validateCoupon = function (form) {
var textCoupon = form.textCoupon,
value = textCoupon.value,
track = function (value) {
_gaq.push(['_trackEvent', 'Coupon', 'Activated', value]);
};
if (value.length) {
if (value === 'Item01' || value === 'Item02') {
track(value);
}
$.get('/include/checkCoupon.php', { coupon: value }, validateShipping);
} else {
textCoupon.style.border = '';
validateShipping('yes');
}
return false;
};
Formatting of the source code is irrelevant to the JavaScript runtime. It's just a matter of personal taste.
Avoid tabs in indentation: they are not rendered identically on all platforms.