I’m trying to convert user input from a text field into an integer in JavaScript so I can do some math with it, but I keep getting unexpected results like NaN or wrong values. I’m not sure when to use parseInt, Number, or other methods, or how to handle decimals and invalid input safely. Can someone explain the right way to convert a string to an integer in modern JavaScript with a few simple examples?
Use this rule of thumb:
- For plain numeric input, use Number:
const value = Number(input);
Examples:
Number(‘42’) // 42
Number(‘3.14’) // 3.14
Number(’ 10 ‘) // 10
Number(’') // 0
Number(‘42px’) // NaN
If you get NaN, log the input:
console.log(‘input:’, JSON.stringify(input));
Then validate:
const value = Number(input);
if (Number.isNaN(value)) {
// handle invalid input
}
- For integers only, use parseInt with a radix:
const value = parseInt(input, 10);
Examples:
parseInt(‘42’, 10) // 42
parseInt(‘42px’, 10) // 42
parseInt(‘3.14’, 10) // 3
parseInt(‘08’, 10) // 8
Always pass 10 as the second argument. Without it old engines did weird stuff with leading zeros.
- For floats, use parseFloat:
const value = parseFloat(input);
Examples:
parseFloat(‘3.14’) // 3.14
parseFloat(‘3.14px’) // 3.14
- Common gotchas from text fields:
HTML inputs:
const raw = document.getElementById(‘age’).value; // string
const age = Number(raw); // or parseInt(raw, 10)
If the field is type=‘number’, it is still a string in JS.
Trailing or leading spaces do not matter for Number and parseInt. Middle junk does.
- Quick guide:
// want integer, reject ‘10px’
const n = Number(input);
if (!Number.isInteger(n)) error;
// want integer, allow ‘10px’ from sloppy input
const n2 = parseInt(input, 10);
Most of the time, for form data, people do:
const value = Number(input.trim());
Then check with:
if (!Number.isFinite(value)) { /* invalid */ }
Do that and your NaN problems go away or at least become obvious.
Couple of extra angles to add on top of what @hoshikuzu already covered:
-
Decide if you want “strict” or “forgiving” behavior
-
Strict numeric input (form must contain only a number):
const raw = input.trim(); const value = Number(raw); if (!Number.isFinite(value) || !Number.isInteger(value)) { // invalid integer, show error }This will reject things like
'10px'or'3.14'outright, which is usually what you actually want in a form. -
Forgiving integer parsing (try to pull a number out of a messy string):
const value = parseInt(input, 10); if (Number.isNaN(value)) { // nothing usable at the start of the string }This will treat
'10px'as10, but personally I find that behavior often hides user mistakes instead of surfacing them.
-
-
Avoid accidental string concatenation
A super common “it’s not working” issue is this:
const a = document.getElementById('a').value; // string const b = document.getElementById('b').value; // string const sum = a + b; // '2' + '3' => '23'Make sure you convert before math:
const a = Number(document.getElementById('a').value); const b = Number(document.getElementById('b').value); const sum = a + b;Or even more defensive:
const toInt = s => { const n = Number(s.trim()); return Number.isInteger(n) ? n : NaN; }; const a = toInt(document.getElementById('a').value); const b = toInt(document.getElementById('b').value); if (!Number.isFinite(a) || !Number.isFinite(b)) { // show validation error } -
Don’t rely on implicit conversion
Stuff like this “kind of” works but is fragile:
const n = +input; // unary plus const m = input * 1; // multiplication coerces to numberI know some people like it for brevity, but when you’re debugging NaN or weird values from user input, being explicit with
Number()orparseInt()makes it much clearer what’s happening. -
What to do about empty strings
One thing I slightly disagree with compared to @hoshikuzu’s examples is the use of
Number(')in real form code. Yeah, it returns0, but almost no user expects an empty field to mean zero. That’s usually “no value”.I’d do:
const raw = input.value.trim(); if (raw === ') { // treat as missing, not 0 } else { const value = Number(raw); if (!Number.isInteger(value)) { // show error } } -
If you’re using
<input type='number'>Still a string in JS, but you can combine browser validation with your own:
const el = document.querySelector('#age'); if (!el.checkValidity()) { // browser says it's not a valid number in the given constraints } else { const age = Number(el.value); if (!Number.isInteger(age) || age < 0) { // extra validation } }
TL;DR:
- Use
Numberfor strict validation. - Use
parseInt(input, 10)only if you intentionally want to allow junk after the number. - Trim, validate, and never assume empty string means 0.
- Convert before any math so you don’t end up concatenating strings and wondering why
2 + 3 === '23'.