Do I need to use an "=" when using the ? : javascript shortcut? - javascript

Can someone tell me if this is valid javascript to do this:
if (wf.statusId == Status.Dirty) {
wf.createdDate
? promises.push(self.wordFormUpdateSubmit(wf, key))
: promises.push(self.wordFormAddSubmit(wf, key));
}
Would there be cases where this would not work correctly if createdDate was not defined?
Here's what this replaced:
if (wf.statusId == Status.Dirty) {
if (wf.createdDate) {
var updatePromise = self.wordFormUpdateSubmit(wf, key);
promises.push(updatePromise);
} else {
var addPromise = self.wordFormAddSubmit(wf, key);
promises.push(addPromise);
}
}
Also a related question. Would it be possible to use the same syntax with ? : to replace the need for the if () { } construct ?

Using = with ternary operator is not mandatory unless expr1 and expr2 are returning something and you want to save it in some other variable.
In your case, unless promises.push(self.wordFormAddSubmit(wf, key)) and promises.push(self.wordFormUpdateSubmit(wf, key)) are returning something that you want to save it a variable, there is no need for a =.

if (wf.statusId == Status.Dirty) {
promises.push(self[wf.createdDate ? 'wordFormUpdateSubmit' : 'wordFormAddSubmit'](wf, key));
}

wf.createdDate only true if it is not undefined or have value. so this should work fine.
if (wf.statusId == Status.Dirty) {
wf.createdDate
? promises.push(self.wordFormUpdateSubmit(wf, key))
: promises.push(self.wordFormAddSubmit(wf, key));
}
Regards
Mk

This is an example of a ternary statement, using the conditional (ternary) operator, which by definition replaces an if...else construct.
From MDN:
The conditional (ternary) operator is the only JavaScript operator that takes three operands. This operator is frequently used as a shortcut for the if statement.
[source]
Both of your code samples would work the same way, ie if createdDate was undefined the second expression of your ternary statement would run (the line after the :) just like the else block of your if...else construct would run.
The title question seems somewhat unrelated, in that you would only need to use = if you wanted to save a reference to something. In this case, it does not appear that you do.
As for your follow-up question, plenty of people use ternary statements for small checks and tasks that fit on one or a few lines (I personally don't because I prefer the readability of if...else), however anything even moderately complex can quickly make your code hard to read and understand. But yes, technically, ternary statements can replace if...else blocks.

regarding the second question:
assuming you don't need to save the results in a variable, you can do:
promises.push(wf.createdDate?
self.wordFormUpdateSubmit(wf, key) :
self.wordFormAddSubmit(wf, key);
);
and even this works:
promises.push(
(wf.createdDate? self.wordFormUpdateSubmit:self.wordFormAddSubmit)(wf, key)
);

Related

If true … else Shorthand

I know that the normal use case for this if statement is e.g.
var string = boolean ? "this" : "that";
I use jhint in my editor and when i try something like
boolean ? array.push("this") : array.slice("that",1);
jshint throws (W030) "Expected an assignment or function call and instead saw an expression"
So far the code always worked fine but maybe i was just lucky.
So my question is, why should i not use this pattern and what would be an alternative? Because writing
if(boolean){
array.push("this");
} else {
array.splice("that",1);
}
for such short instructions really give me the creeps.
thank you.
It is possible to wrap the ternary operator inside the void operator like this:
void(cond ? expr1 : expr2);
This achieves the desired result and passes JSHint. See JSFiddle and click JSHint button.
However, I recommend the following syntax:
if (cond) {
expr1;
} else {
expr2;
}
Because it is more readable. Just because JavaScript lets you do strange things does not mean that you should.
What it complains about is you misappropriating the conditional operator. It is an operator not a control structure. So it lives in the category of such things things as +,-,*,/. That means you expect the first operand to be a boolean and the second and third to yield a return value.
The whole thing is meant to be short for
if (boolean) {
string ="this" ;
} else {
string ="that";
}
It wants to return a value (which it can't in your case) and it expects you to use that value (which you don't). So the tenary if is not the thing to use for your case and as a result makes it far less readable.
You are using side effects in expressions to execute logic.
Indeed not very friendly code. It will work.
Just rewrite to distinct logic from expressions.
You can circumvent the jshint message using:
void(boolean ? array.push("this") : array.slice("that",1));
If you really want to use the ternary operater for this kind of operation in a clean way, then you can do it like this:
array[cond ? 'push' : 'slice'](cond ? "this" : "that", cond ? 1 : undefined);
or
array[cond ? 'push' : 'slice'].apply(null, cond ? ["this"] : ["that", 1]);
But anyway you may prefer a boring if statement.

Shorthand if ? return : null

I want to achieve this:
if (full) {
return
}
else{
// nuthin
}
But shorter, something like:
full ? return : null;
But that doesn't work..
I could do:
if (full) { return }
But I like the ternary more
I expected something like full ? return to work...
I basically want to break out of the current function when the value is true...
Are there any better/working shorthands available?
The arguments of a ternary are expressions not statements.
return; is a statement so what you're proposing is not syntatically valid.
Your if statement is about as terse as you can make it: especially if you remove unnecessary braces.
Explainations
If you only want the test if true, you can use the logical AND operator && like so:
index.js:
(function(){
var full=true;
full&&alert('Glass is full');
})();
Note that in this example, nothing will happen in case var full=false;.
Source-code
JSFiddle source-code.
Codepen source-code
Pastebin source-files
So this is as short as it gets:
if full return
For those using typescript with all the bells and whistles:
if (condition) return;

Return of function in ternary comparison

simple code but answer not found (maybe I haven't looked deep enough since my main language isn't english..)
getDeviceInfos(deviceIP) ? displayDevice(**return of getDeviceInfos function**) : dead.push=deviceIP;
If getDeviceInfos returns something else than 0 (ie. it == true), i want the return value to be the argument in displayDevice call.
Is there any way to do it or I need to write a "regular" comparison ?
Thanks
You can do the following, but it would need a var to avoid a global variable. As a result, it's not really a straight expression.
var info;
(info = getDeviceInfos(deviceIP)) ? displayDevice(info) : (dead.push = deviceIP);
While this wasn't your question, you can (and perhaps should) do something similar by caching the result with a standard if-else statement, either when you var info, or in the if itself:
var info;
if (info = getDeviceInfos(deviceIP)) {
displayDevice(info);
} else {
dead.push = deviceIP;
}
Provided you're not using the value produced by the ternary expression, I would recommend the latter approach for readability.
First create a variable, then perform the assignment and compare like so -
var a; // <-- A variable.
(a = getDeviceInfos(deviceIP)) ? displayDevice(a) : dead.push = deviceIP;
Based on your update in the comments sections (and for readability's sake), I'd suggest making it a two step check:
var deviceInfo = getDeviceInfos(deviceIP);
(deviceInfo !== 0) ? displayDevice(deviceInfo) : dead.push=deviceIP;
That is a more accurate check of the condition and is easier to read.
Conditional Operator
Multiple ternary evaluations are also possible (note: the conditional operator is right associative).
var hadRelations = false;
var isSure = false;
var presidentQuote = hadRelations ? "Had relations" : isSure ? "Did not have relations" : "I admit";
console.log( presidentQuote ); // Prints "I admit" in the console
I moved it into the function itself..
function getDeviceInfos(pIp)
{
//code
result ? displayDevice(result) : dead[dead.length]=pIp
}
I know this isn't strictly speaking an answer your question, but I'd strongly recommend considering not using the ternary syntax, ever. When writing code, always balance what is the easiest to read and maintain with what is compact, efficient, and cool.
In practice, ternary syntax isn't significantly faster than an if statement, so there's generally no "efficiency" grounds to use it.
Compare:
var info;
(info = getDeviceInfos(deviceIP)) ? displayDevice(info) : (dead.push = deviceIP);
with ...
var info = getDeviceInfos(deviceIP);
if (info) {
displayDevice(info);
} else {
dead.push = deviceIP;
}
Sure, the if-then style is less compact, but it's much easier to understand, debug and extend.
In short, there's almost never a reason to use ternary syntax: it's generally harmful to code quality. Avoid.

javascript question mark ?: logical syntax, defensive programming

I am trying to re-write the statement below using the javascript ?: syntax.
if(type of someVariable !="undefined"){
someFunction(someVariable);
}else{}
This is my current attempt and it's causing a syntax error
typeof someVariable != "undefined" ? someFunction(someVariable) : ;
If any one can tell met what I'm doing wrong I'd appreciate it. Any accompanying tips on best practices for defensive programing are welcome.
?: style (requires expressions on either side of the :):
typeof(someVariable) != 'undefined' ? someFunction : null;
Ninja-style:
someVariable !== undefined && someFunction(someVariable);
[Edit: I couldn've sworn noop was a thing in Javascript, but apparently I was wrong. Switched to null]
even though the ternary operation controls the program flow, I'd use it only in assignment operation or when returning a value from a function.
check this out:
Benefits of using the conditional ?: (ternary) operator
It should look like this.
someVariable != undefined ? someFunction(someVariable):someOtherfunction(someOtherVarialbe);
if you do not want else statement and want it in single line you can do like this:
if(someVariable != undefined){someFunction(someVariable);}

JavaScript: Error - "Expected an assignment or function call and instead saw an expression"?

I am using JSLint to ensure my JavaScript is "strict" and I'm getting the following error:
Expected an assignment or function call and instead saw an expression
On the following code:
(my_var > 0 ) ? $("#abc").html(my_array.join('')) : $("#abc").html('<h2>Hello ' + persons_name);
Any ideas why I'm getting such an error? Also, I'm using jQuery as seen in the above code, in case that makes a difference.
My guess would be that JSLint is unhappy since you're using the ternary operator, and you're not doing anything with the value. Refactoring this into the equivalent:
if (my_var > 0 ) {
$("#abc").html(my_array.join(''));
} else {
$("#abc").html('<h2>Hello ' + persons_name);
}
would eliminate the error. If for some reason you're really attached to using the ternary operator, the "right" way to use it would be:
$("#abc").html((my_var > 0) ? my_array.join('') : '<h2>Hello ' + persons_name);
I believe this is because the ternary operator evaluates the expression and returns a value that is expected to be assigned. For example:
var test = (my_var > 0) ? true : false;
However, you are using it like a regular if/then/else statement. While the ternary operator does perform if/then/else, it is traditionally used in assignents.
EDIT: As an addendum: would this statement make sense to you?
var foo = 1;
(my_var > 0) ? true : false;
console.log('hello world');
you are using an expression (an expression using the ternary operator to be precise) in a single line: your line is comprised uniquely of an expression.
this is considered poor programming practice in many language, and could be rewritten using an if statement to render this line more clear.
Just asked the same Q without finding this one for some reason...
The ternary returns a value that isn't being used so you're abusing the ternary structure by not using the value (even though the function calls are being made as intended).

Categories