isNaN not catching letters - javascript

I have JS code to validate a Zip Code: 10 numeric chars with a dash in the 6th position (e.g., 12345-6789). I verify that both parts are numbers using !isNaN.
if (valSize == 10) {
var numVal1 = new Number(newVal.substring(0, 4));
var numVal2 = new Number(newVal.substring(6, 9));
if (newVal.charAt(5) == '-' && !isNaN(numVal1) && !isNaN(numVal2)) {
return newVal;
}
}
throw "Incorrect format";
This mostly works, but for some reason the following value goes through, and an error is NOT returned:
12345-678a
Why is !IsNaN(substring(6,9)) allowed to pass in this case?

String.substring function signature is:
str.substring(indexA[, indexB])
indexA
An integer between 0 and the length of the string, specifying the
offset into the string of the first character to include in the
returned substring.
indexB
Optional. An integer between 0 and the length of the string, which
specifies the offset into the string of the first character NOT to
include in the returned substring.
So you have:
"12345-678a".substring(0,4) // 1234
"12345-678a".substring(6,9) // 678
So either correct the indices:
"12345-678a".substring(0,5) // 12345
"12345-678a".substring(6) // 678a
Or use String.substr.
Or use regex (recommended) since your current code, after fixing, would happily accept 12.45-67.8, +1234--678 and 12e45-6e-9. All you need to do is this:
/^\d{5}-\d{4}$/.test("12345-678a") // false
/^\d{5}-\d{4}$/.test("12.45-67.8") // false
/^\d{5}-\d{4}$/.test("12345-6789") // true

Would a regex not be the more proper test?
/\d{5}-\d{4}/.test('12345-1234')
true
/\d{5}-\d{4}/.test('12345-123a')
false

newVal.substring(6,9) in the case of the string "12345-678a" would return "678" which is a number. So there should not be an error thrown.

Related

JavaScript - Check if input is a number

I'm facing the following (basic) problem: I want to check if an input from an HTML-input field is not greater than 5 or not a number. If this is given the function should return true. Otherwise (so if greater than 5 or a number) it should resturn false. The validation if the number is not greater than 5 works fine so far but when I add the typeof-argument this one doesn't works.
This is my code so far, thanks in advance!
function isValidStart(start) {
if (start.trim().length > 5 || typeof(start) === 'number') {
return false
}
return true
An Element.value (input, select, textarea etc) will always be a String.
Test if a single-digit integer range is used can be achieved with a small Regex and RegExp.prototype.test().
Test an integer of length 5
const isValidStart = v => /^\d{1,5}$/.test(v); // or use [0-5]
console.log(isValidStart("1")) // true
console.log(isValidStart("55555")) // true
console.log(isValidStart(2)) // true
console.log(isValidStart("a12")) // false
You don't even have to care if a value is a String or Number.
Single integer:
to match single digits from range 1 to 5:
const isValidStart = v => /^[1-5]$/.test(v); // or use [0-5]
console.log(isValidStart("1")) // true
console.log(isValidStart(2)) // true
console.log(isValidStart("a")) // false
console.log(isValidStart("6")) // false
You can use the Number.isFinite() function to check if a variable is a finite number, which in your use case should do the Job.
let intVar = 2;
Number.isFinite(intVar);
$true
However it looks like your start variable is not actually a number as you can't call .trim() on a number. So this if statement will never return True.
You should typecast your variable. https://www.w3schools.com/js/js_type_conversion.asp
let reg = new RegExp(/^\d{0,5}$/);
console.log(reg.test('1'));
console.log(reg.test('12'));
console.log(reg.test('123'));
console.log(reg.test('1234'));
console.log(reg.test('12345'));
console.log(reg.test('string'));
console.log(reg.test('124var123'));

parse integer with javascript using parseInt and a radix

I am doing an online test and it asks me to write basic javascript code.
It asks me to parse a numberic string and convert it to a number of a different base. It needs me to return -1 if for whatever reason the conversion cannot be done.
I have written this:
function convert(strNumber, radix) {
var result = parseInt(strNumber, radix);
if(isNaN(result))
{return -1;}
return result;
}
Then it runs my code through various tests and all pass. Except one.
Apparently convert("ASD", 15) should be invalid according to the test and it expects it to be -1.
But Javascript happily converts it to number 10
I tried various things such as to add a try{}catch{} block and other things, but javascript never complains about converting "ASD" to base 15.
Is the test wrong, or is parseInt wrong?
By the way strNumber can be any base under 36.
So for instance:
convert("Z", 36) is 35
As I stated in the comment, parseInt will convert up to the point where it fails. So "A" is valid in that radix and "S" is not. So you would need to add a check.
var nums = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".substr(0, radix)
var re = new RegExp("^[" + nums + "]+$","i")
if (!re.test(strNumber)) {
return -1
}
parseInt is behaving normally and is converting the letter A into 10 in base 15 (similar to how hex uses A for the number 10). The S and D are discarded, as parseInt accepts this type of malformed input.
From the parseInt documentation:
If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point.
As per official documentation the parseInt function behaves as following
For radices above 10, the letters of the alphabet indicate numerals
greater than 9. For example, for hexadecimal numbers (base 16), A
through F are used.
and
If parseInt encounters a character that is not a numeral in the
specified radix, it ignores it and all succeeding characters and
returns the integer value parsed up to that point.
Thus to prevent invalid arguments from being parsed they have to be validated first
function convert(strNumber, radix) {
if (isValidRadix(radix) && isValidInteger(strNumber, radix))
return parseInt(strNumber, radix);
return -1;
}
function isValidInteger(str, radix) {
var letters = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'].slice(0,radix);
str = str.toUpperCase();
for (var i=0; i<str.length; i++) {
var s = str.charAt(i);
if (letters.indexOf(s) == -1) return false;
}
return true;
}
function isValidRadix(radix) {
// 16 up to HEX system
return radix > 0 && radix <= 16;
}
console.log(convert("ASD", 15));
console.log(parseInt("ASD", 15));
console.log(convert("AAA", 15));

Checking if the first character of a string is a number gives an error that charat is not a valid method

I have a method that validates a field against 3 regex expressions and returns an error based on which expression failed.
function mfpValidateValue()
{
var pCtrl = window.document.forms[0].txtValue;
var pStrValue = mTrim(pCtrl.value);
if (pStrValue == '')
return true;
var regexNum = new RegExp("^[0-9]{9}.{0,3}$"); // First 9 are numeric followed by up to any 3 characters
var regexLetter1 = new RegExp("^[A-Z]{1,3}[0-9]{6}$"); //Up to the first 3 are alpha, then there are exactly 6 numbers
var regexLetter2 = new RegExp("^[A-Z]{1,3}[0-9]{9}$"); //Up to the first 3 are alpha, then there are exactly 9 numbers
var error = "";
// If any of the RegEx fails, set base error message
if (!regexNum.test(pStrValue) || !regexLetter1.test(pStrValue) || !regexLetter2.test(pStrValue))
error = "Please enter a valid Value.";
// Set more specific error message.
if (!isNaN(pStrValue.charat(0)))
error += " If the first character of Value is a digit, then the first nine characters must be digits.";
else
error += " If the first character of Value is a letter, up to the first three characters must be letters proceeded by 6 or 9 digits.";
return (error == "");
}
I get the following error message on this line:
if (!isNaN(pStrValue.charat(0)))
Object doesn't support property or method 'charat'
And the value in pStrValue is:
"12345678"
Is JavaScript using the term "object" ambiguously here to refer to my particular variable, or does it actually think pStrValue is an object and not a string?
You have a minor mistake. charat() is not a function, but charAt() is.
Your code should be
if (!isNaN(pStrValue.charAt(0)))
Here is the function
http://www.w3schools.com/jsref/jsref_charat.asp
You check this:
if not is Not a Number
The new ECMAScript 2015 (ES6) has a new method:
Number.isInteger(value)
Mozilla Developer Network describes:
If the target value is an integer, return true, otherwise return false. If the value is NaN or infinite, return false.
See full information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
A proper alternative is:
if (Number.isInteger(parseInt(pStrValue.charAt(0))))

Integer Comparison

I need to compare two Integers which could exceed Integer range limit. How do I get this in javascript.
Initially, I get the value as String, do a parseInt and compare them.
var test = document.getElementById("test").value;
var actual = document.getElementById("actual").value;
if ( parseInt(test) == parseInt(actual)){
return false;
}
Any options to use long ? Also, which is best to use parseInt or valueOf ??
Any suggestions appreciated,
Thanks
You'd better to assign the radix. Ex. parseInt('08') will give 0 not 8.
if (parseInt(test, 10) === parseInt(actual, 10)) {
Leave them in String and compare (after you have cleaned up the string of leading and trailing spaces, and other characters that you consider safe to remove without changing the meaning of the number).
The numbers in Javascript can go up to 53-bit precision. Check whether your number is within range.
Since the input is expected to be integer, you can be strict and only allow the input to only match the regex:
/\s*0*([1-9]\d*|0)\s*/
(Arbitrary leading spaces, arbitrary number of leading 0's, sequence of meaningful digits or single 0, arbitrary trailing spaces)
The number can be extract from the first capturing group.
Assuming integers and that you've already validated for non-numeric characters that you don't want to be part of the comparison, you can clean up some leading/trailing stuff and then just compare lengths and if lengths are equal, then do a plain ascii comparison and this will work for any arbitrary length of number:
function mTrim(val) {
var temp = val.replace(/^[\s0]+/, "").replace(/\s+$/, "");
if (!temp) {
temp = "0";
}
return(temp);
}
var test = mTrim(document.getElementById("test").value);
var actual = mTrim(document.getElementById("actual").value);
if (test.length > actual.length) {
// test is greater than actual
} else if (test.length < actual.length) {
// test is less than actual
} else {
// do a plain ascii comparison of test and actual
if (test == actual) {
// values are the same
} else if (test > ascii) {
// test is greater than actual
} else {
// test is less than actual
}
}

Check if string contains only digits

I want to check if a string contains only digits. I used this:
var isANumber = isNaN(theValue) === false;
if (isANumber){
..
}
But realized that it also allows + and -. Basically, I want to make sure an input contains ONLY digits and no other characters. Since +100 and -5 are both numbers, isNaN() is not the right way to go.
Perhaps a regexp is what I need? Any tips?
how about
let isnum = /^\d+$/.test(val);
string.match(/^[0-9]+$/) != null;
String.prototype.isNumber = function(){return /^\d+$/.test(this);}
console.log("123123".isNumber()); // outputs true
console.log("+12".isNumber()); // outputs false
If you want to even support for float values (Dot separated values) then you can use this expression :
var isNumber = /^\d+\.\d+$/.test(value);
Here's another interesting, readable way to check if a string contains only digits.
This method works by splitting the string into an array using the spread operator, and then uses the every() method to test whether all elements (characters) in the array are included in the string of digits '0123456789':
const digits_only = string => [...string].every(c => '0123456789'.includes(c));
console.log(digits_only('123')); // true
console.log(digits_only('+123')); // false
console.log(digits_only('-123')); // false
console.log(digits_only('123.')); // false
console.log(digits_only('.123')); // false
console.log(digits_only('123.0')); // false
console.log(digits_only('0.123')); // false
console.log(digits_only('Hello, world!')); // false
Here is a solution without using regular expressions:
function onlyDigits(s) {
for (let i = s.length - 1; i >= 0; i--) {
const d = s.charCodeAt(i);
if (d < 48 || d > 57) return false
}
return true
}
where 48 and 57 are the char codes for "0" and "9", respectively.
This is what you want
function isANumber(str){
return !/\D/.test(str);
}
in case you need integer and float at same validation
/^\d+\.\d+$|^\d+$/.test(val)
function isNumeric(x) {
return parseFloat(x).toString() === x.toString();
}
Though this will return false on strings with leading or trailing zeroes.
Well, you can use the following regex:
^\d+$
if you want to include float values also you can use the following code
theValue=$('#balanceinput').val();
var isnum1 = /^\d*\.?\d+$/.test(theValue);
var isnum2 = /^\d*\.?\d+$/.test(theValue.split("").reverse().join(""));
alert(isnum1+' '+isnum2);
this will test for only digits and digits separated with '.' the first test will cover values such as 0.1 and 0 but also .1 ,
it will not allow 0. so the solution that I propose is to reverse theValue so .1 will be 1. then the same regular expression will not allow it .
example :
theValue=3.4; //isnum1=true , isnum2=true
theValue=.4; //isnum1=true , isnum2=false
theValue=3.; //isnum1=flase , isnum2=true
Here's a Solution without using regex
const isdigit=(value)=>{
const val=Number(value)?true:false
console.log(val);
return val
}
isdigit("10")//true
isdigit("any String")//false
If you use jQuery:
$.isNumeric('1234'); // true
$.isNumeric('1ab4'); // false
If you want to leave room for . you can try the below regex.
/[^0-9.]/g
c="123".match(/\D/) == null #true
c="a12".match(/\D/) == null #false
If a string contains only digits it will return null

Categories

Resources