I'm getting a numeric value from a form. Then I check to see if it's NaN. If it is a number I want to set that value to a variable. The problem is that when I enter a valid number I still get an alert and the number isn't passed to the variable "date". How should I modify my statement so that when it is a valid number I can assign it to the variable date?
var adate = document.getElementById("dueDate").value;
if ( adate == NaN || " ") {
alert("Please enter a due date");
return;
}
else {
var date = (new Date()).setDate(adate);
}
processDate(date);
Use Javascript's isNaN() function.
Checking equality with NaN is always false, as per IEEE's standards.
Stephen Canon, a member of the IEEE-754 committee that decided this, has an excellent answer explaining this here.
As strange as it seems, NaN !== NaN.
if (adate !== adate || adate !== " ") {
//...
}
The isNaN function would work in a lot of cases. There is a good case to be made that it is broken, though.
One nice way of getting around this is:
MyNamespace.isNaN = function (x) {
return x !== x;
}
you could Use if( isNaN(adate))
good luck
You have two problems here. The result is that the conditional will always pass. This is what it does:
adate == NaN // first, test if adate == NaN (this always returns false)
|| // if the first test fails (i.e. always), carry on checking
" " // test if the string " " is truthy (this always returns true)
The || does two separate checks. It does not test to see if adate is "either NaN or " "", which seems to be what you expect.
Your code might as well say
if ( true ) {
You would be able to sort this out, however, if you tried two comparisons:
if ( (adate == NaN) || (adate === " ")) {
As other people have said, however, this doesn't work, because NaN !== NaN. So the solution is to use isNaN:
if (isNaN(adate) || (adate === " ")) {
By using isNaN method we can verify if the given input is number or not.
let num1 = parseInt(prompt('Enter your number-1'));
let num2 = parseInt(prompt('Enter your number-2'));
alert(num1 + " is of type " + typeof num1 + " & " + num2 + " is of type " + typeof num2);
if (isNaN(num1) || isNaN(num2)) {
alert("Can not add incompatible types");
} else {
let sum = num1 + num2;
alert("Sum is " + sum);
}
Related
I have a following task from my mentor:
Type a value with a prompt and make it a number with unary plus
console.log if it's even or odd
If it's not a number, add another console log
Here's the code I have right now, and I can't really understand what's wrong:
x = prompt("Enter your value: ");
if(x % 2 === 0) {
console.log("x is an even number");
} else {
console.log("x is an odd number")
}
if (typeof x === "!Number"){
console.log("Whoops, it seems like you're mistaken");
}
There're several issues in your code:
You should check the type of x before you judge it's even or odd.
The type of x can only be string since it's come from prompt, but you can still know if it's a valid number string by isNaN() function.
If you want to know whether a type of a variable is number or not, it should be typeof x !== 'number'. typeof x === '!Number' will never be true(also the case matters).
Here's an example that how you could write the code:
let x = prompt("Enter your value: ");
if (isNaN(x)){
console.log("Whoops, it seems like you're mistaken");
} else if(x % 2 === 0) {
console.log("x is an even number");
} else {
console.log("x is an odd number")
}
I need to make sure that my string is a number and for doing that, I was using isNaN function and everything was working but I got a problem when I typed in my input field '0e1'.
I was wondering what's the best way to check if my string is a number and without scientific notation
Try using regex. Here are some examples. The result is null if no match was found.
alert("0e1".match(/^[-+]?[0-9]*\.?[0-9]+$/)) // null
alert("1".match(/^[-+]?[0-9]*\.?[0-9]+$/)) // 1
alert("-1".match(/^[-+]?[0-9]*\.?[0-9]+$/)) // -1
alert("1.0".match(/^[-+]?[0-9]*\.?[0-9]+$/)) // 1.0
alert("-1.5".match(/^[-+]?[0-9]*\.?[0-9]+$/)) // -1.5
alert("-1.5 4".match(/^[-+]?[0-9]*\.?[0-9]+$/)) // null
If you want your input to only be an integer or float do this instead;
var input = '0e1';
if(!isNaN(input) && (parseInt(input, 10).toString() == input || parseFloat(input).toString() == input)){
//This is a valid number
}
Actually, the method you are using is fine. You have one problem with your code:
isNaN() should be !isNaN(). Remember, isNaN() checks if the number is NotaNumber. `!isNaN() checks if it IS a number.
isNaN(0e1) should return false because 0e1 is a number! I know, it's kind of confusing.
!isNaN(0e1) will return TRUE because !isNan() checks if a value IS a number.
I hope this helps.
isNaN() function determines whether a value is an illegal number, so if it is not a number. The good thing about isNaN function is, that is suportet by all browsers (ch, ie, ff, op, sf).
function myFunction() {
var a = isNaN(123) + "<br>";
var b = isNaN(-1.23) + "<br>";
var c = isNaN(123-456) + "<br>";
var d = isNaN("Hello") + "<br>";
var e = isNaN("2014/11/19") + "<br>";
var result = a + b + c + d + e;
document.getElementById("test").innerHTML = result;
}
So result would be: If value is a number return "False" if is not a number return "True".
You can test it on JsFiddle: isNaN()
I'm trying to make a simple addition tool to add 2 values together, I'm just having a little trouble with the NaN checking... would like to print "Please insert numbers only" if either A or B, or both are NaN.
function getTotal() {
var a = parseInt(document.addBoxes.boxA.value);
var b = parseInt(document.addBoxes.boxB.value);
if (total != NaN) {
total = a+b;
document.getElementById("total").innerHTML = "The sum is " + total + ".";
}
else if (a === NaN || b === NaN){
document.getElementById("total").innerHTML = "Please insert numbers only.";
}
else if (a === NaN && b === NaN){
document.getElementById("total").innerHTML = "Please insert numbers only.";
}
};
Also, if there is a performance-friendly way to do this, or a better method.
Thanks!
Checking each individual value for NaN is not required.
function getTotal() {
var a = parseInt(document.addBoxes.boxA.value);
var b = parseInt(document.addBoxes.boxB.value);
var total = a + b;
if (!isNaN(total)) {
document.getElementById("total").innerHTML = "The sum is " + total + ".";
} else {
document.getElementById("total").innerHTML = "Please insert numbers only.";
}
}
Several problems in your code.
Line 4: if (total != NaN) {
total hasn't been defined yet. You should define it in a var beforehand if you don't want to leak globals.
var total = a + b;
Also, NaN will never equal itself so this kind of equality is dangerous. Either use the built-in isNaN() function to check for NaN or (since you mentioned performance-friendly) you can skip the function invocation and use:
if (total !== total) {
Since NaN is the only thing in javascript that doesn't equal itself. Notice I'm using a strict not-equals, we don't want any coercion. This might be a bit too abstract and people who look at the code later (including yourself) might have forgotten this unique property of NaN so I'd prefix this conditional with a comment and perhaps a link to the MDN - Necessity of isNaN page.
Your code might end up looking something like simonzack's answer.
I am currently writing a JS rules engine which at one point needs to evaluate boolean expressions using the eval() function.
Firstly I construct an equation as such:
var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
" " + "relation.value";
relation.relatedTrigger.previousValue is the value I want to compare.
relation.operator is the operator (either "==", "!=", <=, "<", ">", >=").
relation.value is the value I want to compare with.
I then simply pass this string to the eval function and it returns true or false as such:
return eval(equation);
This works absolutely fine (with words and numbers) or all of the operators except for >= and <=. E.g. When evaluating the equation:
relation.relatedTrigger.previousValue <= 100
It returns true when previousValue = 0,1,10,100 & all negative numbers but false for everything in between.
I would greatly appreciate the help of anyone to either answer my question or to help me find an alternative solution.
Regards,
Augier.
P.S. I don't need a speech on the insecurities of the eval() function. Any value given to relation.relatedTrigger.previousValue is predefined.
edit: Here is the full function:
function evaluateRelation(relation)
{
console.log("Evaluating relation")
var currentValue;
//if multiple values
if(relation.value.indexOf(";") != -1)
{
var values = relation.value.split(";");
for (x in values)
{
var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
" " + "values[x]";
currentValue = eval(equation);
if (currentValue)
return true;
}
return false;
}
//if single value
else
{
//Evaluate the relation and get boolean
var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
" " + "relation.value";
console.log("relation.relatedTrigger.previousValue " + relation.relatedTrigger.previousValue);
console.log(equation);
return eval(equation);
}
}
Answer: Provided by KennyTM below. A string comparison doesn't work. Converting to a numerical was needed.
You didn't show how relation.relatedTrigger.previousValue is obtained, but I guess the type of this variable is still a string. In this case, the right hand side will be treated as a string instead. A string comparison matches all characteristics you mentioned:
>>> '-213' <= '100'
true
>>> '0' <= '100'
true
>>> '1' <= '100'
true
>>> '2' <= '100'
false
>>> '10' <= '100'
true
>>> '13' <= '100'
false
You need to make sure relation.relatedTrigger.previousValue is a number. One solution is use the unary + operator in the comparison, e.g.
+relation.relatedTrigger.previousValue <= 100
This has nothing to do with eval. The problem is the overly liberal implicit conversion in Javascript.
Edit: By the way, instead of eval, you could use a dictionary of functions instead. This is faster and also safer. See http://jsperf.com/eval-vs-function-map.
var fmap = {
'>=': function(a, b) { return a >= b; },
...
};
fmap[relation.operator](+relation.relatedTrigger.previousValue,
+relation.value);
It is comparing strings not numbers.
Make sure that relation.relatedTrigger.previousValue and relation.value are numbers.
"11" > "100": Because 11 comes after 100 in alphabetical order.
11 < 100 in numeric order.
var relation = {'relatedTrigger':{'previousValue':"7"}, 'operator':'<=', 'value': "100"};
var equation = "parseFloat(relation.relatedTrigger.previousValue)" + " " + relation.operator +
" " + "parseFloat(relation.value)";
alert(equation + ", " + eval(equation));
This is effectively what you end up with and the extra step to ensure numeric value, not strings are passed seems to work.
Which one of these to JS snippets are better in terms of style?
var answer = Number(prompt('What is the value of 2 + 2?'));
if (answer === 4) {
// do something
}
vs.
var answer = prompt('What is the value of 2 + 2?');
if (answer == 4) {
// do something
}
I'd say the first one is better because it is more explicit (and no type coercion will happen).
They are both wrong, because you should use parseInt(XX, 10) for this. And remember, every time you use == Jesus kills a puppy. So always use ===, and therefore: always check against the correct type.
It depends on what you want to do with answer. If the only thing you want to do is compare it, you don't need to convert the type:
var answer = prompt('What is the value of 2 + 2?');
if (answer === "4") {
// do something
}
If you want to end up with a number for comparison and then further processing, Number or the unary plus operator + will convert the output string to a numeric value, or NaN if it is not a valid base 10 number.
var answer = +prompt('What is the value of 2 + 2?');
if (answer === 4) {
// do something
}
There is a difference between parseInt(x, 10) and Number(x) - the former will ignore non-numeric characters at the end.
parseInt("4Hello World"); // 4
Number("4Hello World"); //NaN
+"4Hello World"; //NaN
Well of course the first one because, as you mentioned, no type coercion happens.but you should use parseInt:
var answer = parseInt((prompt('What is the value of 2 + 2?'), 10)) ;
Better would be
var n = prompt("What is the value of 2 + 2?");
n = parseInt(n, 10);
//and check