JavaScript if else statement ignored - javascript

I have a simple if statement below:
function calculateTotal() {
if (tanksize != 1 || tanksize != 2) {
var setupPrice = basicPrice + StatPrice() + DigiStatPrice() + IRPrice() + UVPrice() + cagePrice();
var setupPrice2 = toFixed(setupPrice, 2);
} else {
var setupPrice = basicPrice;
var setupPrice2 = toFixed(setupPrice, 2);
}
//display the result at the top of page
var divobj = document.getElementById('totalPrice');
divobj.innerHTML = "£" + setupPrice2;
//display the result at the bottom of page
var divobj = document.getElementById('totalPrice2');
divobj.innerHTML = "£" + setupPrice2;
}
But when the tanksize variable is set to 1 or 2, the setupPrice variable is still calculated by adding the basicPrice + StatPrice...etc.

You need to use:
if (tanksize !== 1 && tanksize !== 2) {
with the && operator, or
if (!(tanksize ===1 || tanksize === 2)) {
In your code, you have the first block executing any time the value is not 1 or is not 2, which equates to it always executing.
If the value is 1, then tanksize != 2 is true so tanksize!=1 || tanksize!=2 is true.
If the value is 2, then tanksize != 1 is true so tanksize!=1 || tanksize!=2 is true.
In other words, tanksize!=1 || tanksize!=2 is always true, no matter what the value of tanksize is.

This statement is always true:
if(tanksize!=1 || tanksize!=2){
because, when tanksize = 1, tanksize is different of 2
and when tanksize = 2, tanksize is different of 1.
It is not a javascript error, you just need to change your logic to make the right test in the if...

Try if(tanksize!=1 && tanksize!=2){ instead of if(tanksize!=1 || tanksize!=2){

Your Logic is wrong..
As a matter of fact, OR Operator for two NOT EQUALS is always TRUE ( check boolean table for this) and the conditional statement "if" checks for TRUE or FALSE, hence your code will always return TRUE
Use something like
if(tanksize!=1 && tanksize!=2){
# Your code
}

(tanksize!=1 || tanksize!=2) always will be true by this statement. Change operator || to &&

your first condition is always true, cuz for example if some x = 1, is different of 2 and vice versa.
so this condition is kind of equal to.
if(true) {
// ...
}

Related

Comparing date to NaN and undefined

I have a pretty simple if statement but I don't use javascript too much so I think I have made an error somewhere. If you go to my page you can see the value gets alerted as undefined, but a block of code still gets skipped even though the if parameters are == undefined. Does it matter that this is an AngularJS app?
web page: http://alainwebdesign.ca/pl2/#/petType
javascript:
$scope.setDate = function (dateSelected) {
alert(dateSelected);
var now = new Date();
$scope.latest = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes());
$scope.hoursAgo = Math.round((($scope.latest - dateSelected) / 3600000) * 100) / 100;
if ($scope.hoursAgo === undefined || $scope.hoursAgo == NaN) {
alert("Please choose a date/time");
}
else {
alert('You lost your pet ' + $scope.hoursAgo + ' hour(s) ago');
$scope.checkDateSet = true;
}
}
Your problem is not with your if statement. NaN in Javascript is somewhat special.
For example:
NaN === NaN // false
You can read about it more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN
Change your check to:
if ($scope.hoursAgo === undefined || isNaN($scope.hoursAgo)) {
...
} else {..}
To check if ($scope.hoursAgo === undefined || $scope.hoursAgo == NaN)
write like this
if ($scope.hoursAgo === 'undefined' || isNaN($scope.hoursAgo)) {

Simple javascript if statement with charAt is not working

Its simple, if a user enters a number that does not beggin with 6 or 9, he gets error:
console.log($(this).val().charAt(0));
if($(this).val().charAt(0) != 6 || $(this).val().charAt(0) != 9){
x=false;
}else {
x=true;
}
Console.log correctly displays the first character.. that means the value exists..
But no matter if I type 6 or 7 or 9, i will always get false... Why?
Whatever the value of somevar,
somevar!=6 OR somevar!=9
is always true.
The best solution here would probably be a regular expression:
var x = /^[69]/.test($(this).val());
You need to invert the logic conditions as both states cannot possibly be true at the same time, so x is always set to false. Try this:
var chr = $(this).val().charAt(0);
if (chr == '6' || chr == '9') {
x = true;
} else {
x = false;
}
From there you can now see that you don't even need the if condition as you can set x directly, like this:
var chr = $(this).val().charAt(0);
var x = chr == '6' || chr == '9';

"+" behaving strangely in my functions

i'm making a mathematics app.
there, i want to be able to generate mathematic tasks with randomized operations.
var generator = {
operations: [
"+",
"-",
"*",
"/"
],
randomOperation: function(amount) {
if (amount == 2) {
return this.operations[Math.round(Math.random())];
}
if (amount == 4) {
return this.operations[Math.floor(Math.random() * 4)];
}
},
addOperand: function(operand, maxSize, minSize) {
var op = operand;
console.log('op ' + op);
if (operand == 2||4) {
console.log('getting random operand');
op = this.randomOperation(operand);
}
var number = this.randomNumber(maxSize, minSize);
console.log('number ' + number);
this.tasks.push({
value: number,
operation: op
});
console.log('added ' + op + ' ' + number);
}
// other stuff
}
so i want to be able to call the method with varying arguments:
'+', if i definitely want it to be a +
'-', if i want a -
and so on
if i pass a number (2 or 4), it is supposed to generate randomly out of 2 (+-) or 4 (+-*/)
but something really strange happens...
the console output is:
op +
getting random operand
number 2
added undefined 2
why is '+' considered 2||4 ?
it is clearly coming in as '+', but then somehow... passed to randomOperation(), which, of course, returns nothing.
thanks
PS: is there a way to paste code on here without the pain of manually correcting all the indentations? it's really annoying :(
The expression operand == 2 || 4 is parsed as (operand == 2) || 4.
It will be true if operand == 2, or 4 otherwise.
Both possible results are "truthy", and therefore the if branch is always taken, regardless of the value of operand
If instead you want the branch to be taken only if the operand is 2, or 4, you need:
(operand == 2 || operand == 4)
This:
if (operand == 2||4) {
doesn't mean "if operand == 2, or operand == 4" -- it means "if operand == 2, then true, otherwise 4.
You want to say:
if ((operand == 2) || (operand == 4)) {
That is not how you can check to see if a value is one or the other. What that code is doing is
if ( (operand==2) || 4 )
So id operand is 2 it is true, else it returns 4 which is truthy value. So basically it will always be true.
The check needs to be
if( operand == 2|| operand == 4)
or you can use modulus
if (operand %2 === 0)
or indexOf
if ([2,4].indexOf(operand)>-1)

Extended Ternary expression

I know you can do ternary expressions in Javascript for an if - else statement, but how about an else- else if- else statement? I thought that surely this would be supported but I haven't been able to find any info about it and wasn't able to get it to work just hacking around.
In contrast to Robby Cornelissen's answer - there is no problems with readability if you format it properly (and not writing PHP, since it messed up the operator by making it left-associative in contrast to all other languages that have that construct):
var y =
x == 0 ? "zero" :
x == 1 ? "one" :
"other";
EDIT
What I was looking for is a shorter version of "if expression 1 is true, return expression 1. Else if expression 2 is true, return expression 2. Else return expression 3". Is there no clean way to do this?
There is: expression1 || expression2 || expression3. (It would have been nice if you had put this into your question in the first place.) This is commonly used for default values:
var defaults = null;
function hello(name) {
var displayName = name || (defaults && defaults.name) || "Anonymous";
console.log("Hello, " + displayName + ".");
}
hello("George");
// => Hello, George.
hello();
// => Hello, Anonymous.
defaults = {};
hello();
// => Hello, Anonymous.
defaults.name = "You"
hello();
// => Hello, You.
However, it is important to be aware of the conditions for truthiness. For example, if you expect "" or 0 to be a valid value that does not need to be replaced by a default, the code will fail; this trick only works when the set of possible non-default values is exactly the set of truthy values, no more and no less. E.g.
function increment(val, by) {
return val + (by || 1); // BUG
}
increment(10, 4);
// => 14
increment(10, 1);
// => 11
increment(10);
// => 11
increment(10, 0);
// => 11 <-- should be 10
In this case you need to be explicit:
function increment(val, by) {
return val + (typeof(by) === "undefined" ? 1 : by);
}
I wouldn't recommend it because of readability, but you could just nest ternary operators:
var y = (x == 0 ? "zero" : (x == 1 ? "one" : "other"));
This would be the equivalent of:
var y;
if (x == 0) {
y = "zero";
} else if (x == 1) {
y = "one";
} else {
y = "other";
}
You can extend a ternary condition if you're good. It gets to be messy though.
var number = 5;
var power = 2;
var ans = Math.pow(number,power);
var suggest = ( ans == 5 ? 5 : ans == 10 ? 10 : ans == 15 ? 15 : ans == 25 ? "works" : null);
console.log(suggest);
I may have added to many because I'm on my phone haha but try it in your developer panel.

A quick way to test equality of more than 2 values at once?

I was wondering if there was a quick way to test the equality of more than two values in js. Something similar to (= 6 6 6).
In the console, I tried things like...
1 == 1 == 1 == 1
true
2 == 2 == 2 == 2
false
0 == 0 == 0
false
0 == 0 == 0 == 0
true
...which was amusing, but also puzzling.
Is there a quick way of doing this in js?
Thanks.
The reason you got unexpected behavior is because we need to adjust your expectations in js a bit ;) 2 == 2 == 2 == 2 does 3 comparisons, all from left to right. The first comparison is the leftmost 2 == 2, which evaluates to true. After that we get the result of the first comparison being compared to (what is in this case) the 3rd 2. Ie, true === 2, which is false. And finally, we get false === 2, which is also false.
It might help to visualize it as such:
(((2 == 2) == 2) == 2)
I think in general a === b && b === c might be what you're looking for.
EDIT: Ah, and sorry I keep switching out the == for ===. It's just habit. And it's a habit I'd recommend. the === operator doesn't do type casting, so it evaluates the value proper, not a casted version of the value.
It's because true == 1 but true != 2
You can try:
function isEquals() {
var flag = true;
for(var i=1; i<arguments.length; i++) flag = flag && (arguments[i] == arguments[0]);
return flag;
}
isEquals(2,2,2); // true
or:
function isEquals() {
var ar = arguments;
return Array.prototype.every.call(arguments, function(a){return a==ar[0];});
}
Yes you can, but you need to use the "Logical Operators" like the && or || to check more than 1 statement like (x<1 && y>0).
You can use this as a quick easy reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
If you have more than three values, it might be more convenient to create a function for use on an array:
function allEqual(arr) {
return arr.every(function (x, i) {
return i === 0 || x === arr[i - 1];
});
}
allEqual([1, 1, 1])
ES6:
function allEqual(...arr) {
return arr.every((x, i) => i === 0 || x === arr[i - 1]);
}
allEqual(1, 1, 1)
As an addition to #vp_arth's answer you could even add a method to the Array prototype
Array.prototype.isHomogeneous = function(){
return Array.prototype.every.call(this, function(c,i,a){ return c === a[0];})
}
So you could do
[1,2,3].isHomogeneous() = false
[1,1,1].isHomogeneous() = true

Categories