nested if statement in one line - javascript

if(something.food == true){
if(something.food.fruit == 'apple' || something.food.fruit == 'mango'){
//do something
}
}
this is clear where food must be true later check it's child object, but how to write this in one line? I mean with single if.

If something.food is true then it can not be an object containing fields as well. Though your current check does check for a "truthy" value, it reads quite strange (thanks for pointing this out T. J. Crowder). Instead you should just leave out the == true part.
The resulting check is:
if (something.food && (something.food.fruit == 'apple' || something.food.fruit == 'mango') {
//do something
}

That's all
if(something.food && (something.food.fruit == 'apple' || something.food.fruit == 'mango')) {
//do something
}
As a petition in the comments, I will explain that.
First we check something.food without == true because we need to check if it exists. Then wrap the rest of code into parenthesis and the expression will run ok

Related

ng click if true, resolves to true when false

I have a ng-click event on an <i> tag that looks like this:
ng-click="parent.Status != 'Open' || (item.Status='Retrospect')"
So if parent.Status is not equals to Open then item Status is set to Retrospect, this is ok.
But I want another check, I want to see if this item is editable, for this I have a bool variable, edit. Naturally I wrote it like this:
ng-click="parent.Status != 'Open' && edit || (item.Status='Retrospect')"
So, I thought that if parent.Status is not equals to Open AND edit equals true my item.Status will be updated, problem is that it was updated no matter if edit was true or false (thinking it's because the first check is true, so it doesn't care about edit)
i also tried it like this, but same problem:
ng-click="(parent.Status != 'Open' && edit) || (item.Status='Retrospect')"
.. using ( )
What am I missing? Should this not be possible?
EDIT: Seems like when doing like this:
ng-click="parent.Status != 'Open' || (item.Status='Retrospect')"
item.Status will be set to 'Retrospect' if parent.Status != 'Open' resovles to false, but the problem still persist.
Also, there may be some confuison here I think, I am not checking if parent.Status != 'Open' OR item.Status='Retrospect' I am running the command item.Status='Retrospect' IF parent.Status != 'Open' equals false
My bad Okay, I am so confused right now, but my code did in fact work, the problem was my understanding of ng-click true/false evaluation and also I used != instead of !== which may have caused some issues.
I will upvote most of the answers (cause all of you were right, just not me) and accept what helped me to understand the most. Thanks all!
Such statements are called as short circuit statements.
but as per the rule for "||"
statement1 || statement2
in above, statement1 is always executed and evaluated, but statement2 is executed only if statement1 evaluates to false.
on contrary, the rule for "&&" is
statement1 && statement2
in above, statement1 is always executed and evaluated, but statement2 is executed only if statement1 evaluates to true.
check the below in console -
var parent = {};
parent.Status = "Close";
var edit = false;
var item = {};
item.Status = ""
parent.Status != 'Open' && edit || (item.Status='Retrospect');
item.Status;
the Status will be updated only when (parent.Status != 'Open' && edit) evaluates to false.
You can refer - http://sampsonblog.com/tag/short-circuit-evaluation
Hope this helps.
(item.Status='Retrospect') should be (item.Status === 'Retrospect') ...
Otherwise you are testing the return value of an assignment, which is always true... :-).
As a side note, always use type-converting equality comparison (=== for == !== for != JavaScript)... (for a quite complete and clear explanation, see here).
Update: From your comment I see you really meant what you wrote... :-)
However, in that case, I'd do:
if (!(parent.Status !== 'Open' && edit)) item.Status = 'Retrospect'
or:
item.Status = (parent.Status !== 'Open' && edit) ? item.Status : 'Retrospect'
In your || construct, item.Status will update if the first condition (parent.Status != 'Open' && edit) is false, not if it is true. Your first code should work the same way.
It may be cleaner and less confusing to write:
if (parent.Status != 'Open' && edit) {item.Status = 'Retrospect';}
I think you better expand the code in a function.
In Html:
ng-click="doThing()"
In the javascript:
doThing() {
if((parent.Status != 'Open') && edit) {
item.Status = 'Retrospect';
}
}
Simply use ternary operator like this:
ng-click="parent.Status != 'Open' && edit = true? item.Status='Retrospect' : item.Status='Somethingelse or null'"

"If" consolidation/avoiding nesting

I'm really trying to avoid nesting in this code snippet...
deal_trade_in_model_1 = document.getElementById('deal_trade_in_model_1').value;
deal_trade_in_amount_1 = document.getElementById('deal_trade_in_amount_1').value;
if (typeof deal_trade_in_model_1 !== 'undefined' && deal_trade_in_model_1 !== null) {
console.log(deal_trade_in_amount_1);
console.log(deal_trade_in_model_1);
if (deal_trade_in_model_1 !== null || deal_trade_in_model_1 !== "") {
if (deal_trade_in_amount_1 == null || deal_trade_in_amount_1 == "") {
console.log('entered into function');
document.getElementById("deal_trade_in_model_1").value = "";
document.getElementById("deal_trade_in_amount_1").value = "";
}
}
}
Basically, what this function does is take the value of two fields... things to know about them and what I want to do to them:
1) They're NOT required
2) If one of them is filled out, the other must be
3) If ONLY one of them is filled out, the user clicks submit, and this part of the function is called upon, I want to delete the value of both of them.
I've tried doing a compound of
&& (and)
and
|| (or)
buttttt it odiously it didn't work.
Primary question: What's the best way to get rid of the nesting (I planned on doing this twice and just swapping the code) that will be the most efficient? This, I want, to be done preferably in the smallest amount of IF statements possible.
Please note: If you change the code a lot, I might not know what you're talking about.. please be prepared to teach me or help me learn!
It sounds like you only want to do something if either of the fields are empty, but not both. Assuming both of the elements are text fields, .value will always return a string. Converting a string to boolean results in false if the string is empty, otherwise true.
So
Boolean(deal_trade_in_model_1) === Boolean(deal_trade_in_amount_1)
will be true if either both fields have a value (both will convert to true) or both fields are empty (both convert to false).
Thus your code can be reduced to
var model_1 = document.getElementById('deal_trade_in_model_1');
var amount_1 = document.getElementById('deal_trade_in_amount_1');
if (Boolean(model_1.value) !== Boolean(amount_1.value)) {
model_1.value = "";
amount_1.value = "";
}

check if html attribute exist and has right value with jquery

Is there a better way for checking an attribute for:
it exist. so value must be false if attribute doesn't exist
Value is correct (boolean)
var isOwner = false;
if ($(selectedItem).is('[data-isOwner="True"]') || $(selectedItem).is('[data-isOwner="true"]')) {
isOwner = true;
} else {
isOwner = false;
}
Now I need to check for 'True' and 'true'...
Thanks
You can convert the value stored in data-isOwner to lower case and only compare the value to 'true'.
if (($(selectedItem).attr ('data-isOwner') || '').toLowerCase () == 'true')
The above use of <wanted-value> || '' will make it so that if the selectedItem doesn't have the attribute data-isOwner the expression will result in an empty string, on which you can call toLowerCase without errors.
Without this little hack you'd have to manually check so that the attribute is indeed present, otherwise you'd run into a runtime-error when trying to call toLowerCase on an undefined object.
If you find the previously mentioned solution confusing you could use something as
var attr_value = $(selectedItem).attr ('data-isOwner');
if (typeof(attr_value) == 'string' && attr_value.toLowerCase () == 'true') {
...
}

Ternary Operators as short conditional statements

Is there anything wrong with using ternary operators in place of longer conditional statements in Javascript, for instance using:
(variable == "dog") ? dog_stuff() : false;
Rather than
if ( variable == "dog" )
{
dog_stuff();
}
This may sound like a stupid question but I just find it's pretty quick and easy to read, I just don't want to be using it if there's a possible drawback?
You could also write
(variable == 'dog') && dog_stuff();
if you don't have an else statement.
A few lines from backbone.js:
options || (options = {});
models = _.isArray(models) ? models.slice() : [models];
model = this.getByCid(models[i]) || this.get(models[i]);
You can group multiple statements, if it's very necessary:
(1==1) && (a=2,b=3)
alert(a); // 2
alert(b); // 3
It's wrong because you're telling your code to execute false. Imagine the following code:
if ( variable == "dog" )
{
dog_stuff();
} else {
false;
}
IMO the 4 line conditional function call is perfectly fine. You can shorthand it to:
if (variable == "dog") dog_stuff();
The only problem with this is if you comment it out, or add 1 more function then things look correct, but don't execute correctly:
if (variable == "dog") dog_walk(); dog_bark(); // dog_bark executes always!
if (variable == "dog") // dog_walk();
earn_cash(); // suddenly earn_cash() is dog-dependent.
As long as the format is easily understood by you and anyone else that may need to read the code, it's fine.

Javascript OR in an IF statement

I am trying to make an if statement in javascript that will do something if the variable does not equal one of a few different things. I have been trying many different variations of the OR operator, but I cant get it to work.
if(var != "One" || "Two" || "Three"){
// Do Something
}
Any ideas? Thanks!
Update:
I have tried this before:
if(var != "One" || var != "Two" || var != "Three"){
// Do Something
}
For some reason it does not work. My variable is pulling information from the DOM i dont know if that would effect this.
Actual Code
// Gets Value of the Field (Drop Down box)
var itemtype = document.forms[0].elements['itemtype' + i];
if(itemtype.value != "Silverware" || itemtype.value != "Gold Coins" || itemtype.value != "Silver Coins"){
// Do Something
}
Your expression is always true, you need:
if(!(myVar == "One" || myVar == "Two" || myVar == "Three")) {
// myVar is not One, Two or Three
}
Or:
if ((myVar != "One") && (myVar != "Two") && (myVar != "Three")) {
// myVar is not One, Two or Three
}
And, for shortness:
if (!/One|Two|Three/.test(myVar)) {
// myVar is not One, Two or Three
}
// Or:
if (!myVar.match("One|Two|Three")) {
// ...
}
More info:
De Morgan's Laws
Edit: If you go for the last approaches, since the code you posted seems to be part of a loop, I would recommend you to create the regular expression outside the loop, and use the RegExp.prototype.test method rather than String.prototype.match, also you might want to care about word boundaries, i.e. "noOne" will match "One" without them...
Assuming you mean "val does not equal One or Two or Three" then De Morgan's Theorem applies:
if ((val != "One") && (val != "Two") && (val != "Three")) {
// Do something...
}
For a shorter way to do it, try this format (copied from http://snook.ca/archives/javascript/testing_for_a_v):
if(name in {'bobby':'', 'sue':'','smith':''}) { ... }
or
function oc(a)
{
var o = {};
for(var i=0;i<a.length;i++)
{
o[a[i]]='';
}
return o;
}
if( name in oc(['bobby', 'sue','smith']) ) { ... }
The method mentioned by Mike will work fine for just 3 values, but if you want to extend it to n values, your if blocks will rapidly get ugly. Firefox 1.5+ and IE 8 have an Array.indexOf method you can use like so:
if(["One","Two","Test"].indexOf(myVar)!=-1)
{
//do stuff
}
To support this method on IE<=7, you could define a method called Array.hasElement() like so:
Array.prototype.hasElement = function hasElement(someElement)
{
for(var i=0;i<this.length;i++)
{
if(this[i]==someElement)
return true;
}
return false;
}
And then call it like so:
if(!["One","Two","Three"].hasElement(myVar))
{
//do stuff
}
Note: only tested in Firefox, where this works perfectly.
In addition to expanding the expression into three clauses, I think you'd better name your variable something other than var. In JavaScript, var is a keyword. Most browsers aren't going to alert you to this error.
Alternate way using an array:
var selected = ['Silverware', 'Gold Coins', 'Silver Coins'];
if ( selected.indexOf( el.value ) != -1 ) {
// do something if it *was* found in the array of strings.
}
Note: indexOf isnt a native method, grab the snippet here for IE:
https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf

Categories