React isNaN with input type number - reactjs

I need to check for NaN before I store a value with useState in my React Hooks application, but it doesn't seem to be checking?
const handleStartValueChange = (value) => {
if (isNaN(parseInt(value)) ) {
setStartValue(0);
}
setStartValue(parseInt(value));
};
This is called from onChange on an input box with type number
<div className="startValueHeader">Start value</div>
<input
value={startValue}
type="number"
className="startValueValue"
onChange={(event) => {
handleStartValueChange(event.target.value);
}}
/>
What am I missing?
The reason I need to check for NaN is I need to store a value of 0 instead of '' when I clear the input field

Number - convert numeric strings and null to numbers
Number('123') // 123
Number('12.3') // 12.3
Number('12.00') // 12
Number('123e-1') // 12.3
Number('') // 0 <--- you need this
Number(null) // 0
Number('0x11') // 17
Number('0b11') // 3
Number('0o11') // 9
Number('foo') // NaN
Number('100a') // NaN
Number('-Infinity') //-Infinity
const handleStartValueChange = value => {
const number = Number(value); // converts '' from empty input -> 0
setStartValue(number)
};
NOTE: If you instead specify defaultValue the input won't display the "0" when empty.

Related

How to no allow negative decimal and 0 value to an input type number in React JS

I have a input box which should not allow negative decimal value and 0 trying to do using charcode as shown below
<input type="number" min="1" name="minValue"
className="input-box removeNumberArrow" value={this.state.minValue}
onChange={this.handleMinChange} onKeyPress={this.validateEntredVal}/>
Below method is called when ever a key is pressed
validateEntredVal = (event) => {
let charCode = (evt.which) ? evt.which : evt.keyCode;
if ((charCode > 31 && (charCode <48 || charCode > 57)) && charCode !== 46) {
evt.preventDefault();
} else {
return true;
}
};
Using the above method it will not allow the characters and negative values. problem it should not allow 0 and decimal as well (means the text box value should always accept value greater than zero)
Please help on the same
min="1" is not working
Add min="0" attribute in min tag.

ReactJS - I implement Binary Search Function, it works only first time

ReactJS - I implement Binary Search Function, it works only first time but after I change the value in the input box, it always return -1 even it has the value in the Array.
Please see the following code:
import React, { useState } from 'react'
import { Container } from 'react-bootstrap'
const binarysearch = () => {
const [ insertValue, setInsertValue ] = useState(0)
var exarr = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]
// Binary Search
const binarySearch = (arr, val) => {
let start = 0, end = arr.length - 1
while (start <= end) {
let mid = Math.floor((start + end)/2)
console.log(mid)
if (arr[mid] === val) {
return mid
}
if (val < arr[mid]) {
end = mid - 1
} else {
start = mid + 1
}
}
return -1
}
// End Binary Search
return (
<div>
<br />
<hr />
<Container>
<h1>Binary Search</h1>
<h4>Array = {JSON.stringify(exarr)}</h4>
<h4>Search <input type="number" onChange={e => setInsertValue(e.target.value)} /></h4>
<h3>Search {insertValue}, Result in location: {binarySearch(exarr,insertValue)}</h3>
</Container>
<hr />
</div>
)
}
export default binarysearch
First Time Load
After Change Input (Search 10 it should return 10 but -1)
The problem is the fact that e.target.value is always a string, even when the input type attribute is set to "number".
So, when you do arr[mid] === val it will be always false, since this is comparing a number to a string.
You can see this behaviour here.
To fix this, do onChange={e => setInsertValue(Number(e.target.value))}.
Or, alternatively, you can use the non strict equality comparison, which is not really recommended, by replacing the === operator by just ==.
Thank you very much #Mario Vernari
I update the below line to change from string to number, it works properly.
(Insert '+' to insertValue)
From
<h3>Search {insertValue}, Result in location: {binarySearch(exarr,insertValue)}</h3>
To
<h3>Search {insertValue}, Result in location: {binarySearch(exarr, +insertValue)}</h3>

How do I validate a number input within a React component

In my return statement, I try to check for a valid number or else assign the value 0. This doesn't seem to work, is there a different way of doing this?
return (
<Input
color="teal"
size="regular"
outline={true}
type={question?.type}
name={question?.name}
value={value ?? ''}
placeholder={question?.placeholder ?? ''}
onChange={(e: React.FormEvent<HTMLInputElement>) => {
if (question?.type === 'number' && Number(e.currentTarget.value) < 1) {
e.currentTarget.value = 0;
}
dispatch(
setResponseGeneric({
property: question?.name,
value: e.currentTarget.value,
})
);
}}
></Input>
);
This is because Number('bad input') returns NaN (Not a Number). NaN is a value which is not smaller or greater than 1. You should change your condition so that it handles those scenarios.
if (question?.type === 'number' && (isNaN(e.currentTarget.value) || Number(e.currentTarget.value) < 1)) {
Also something else, besides your question, changing the element value like you do in here e.currentTarget.value = 0; is bad practice since you're changing it imperatively. It's better to make sure you're changing the state so that the value variable becomes 0 (I'm not sure if that already happens in setResponseGeneric).

Create array of objects with function actions

Is it possible to create an array of objects that perform a function?
For example, like this:
<script>
console.clear();
const acts = [
{ 'inc' : (x) => x+1 },
{ 'dec' : (x) => x-1 }
];
console.log(acts.inc(10));
console.log(acts.dec(15));
</script>
The above gives an error -- TypeError: acts.inc is not a function.
You are almost there! Create an object with "function properties" instead of an array of objects:
acts = {
'inc' : (x) => x+1,
'dec' : (x) => x-1
};
Then,
acts.inc(3)
will return:
4
In your original code, you'd have to use:
acts[0].inc(3)
because it's an array...
You can add a function to the array prototype.
Array.prototype.inc = <function>
For anyone interested, here is how I used the solution chosen along with an example output for each function created (with some options).
<!DOCTYPE html><html lang="en"><head>
<title> Array of Object Functions </title>
<meta charset="UTF-8">
<meta name="viewport" content="width-device-width,initial-scale=1.0, user-scalable=yes"/>
<!-- From: https://stackoverflow.com/questions/62824415/create-array-of-objects-with-function-actions -->
<style>
body { font-size: 1.2em; line-height: 1.6; }
</style>
</head><body>
<pre id='demo'></pre>
<script>
console.clear();
// following used only for screen display testing purposes
var former = console.log; // retain former actions of console.log
var demo=document.getElementById('demo');
console.log = function(...msg){
former(...msg); // maintains existing logging via the console. (optional)
demo.append(msg.join(' ')+'\n'); // output needs to be specified
}
// end of display testing (also shows on console.log display)
const acts = {
'inc' : (x) => x+1,
'dec' : (x) => x-1,
'mul' : (x,y) => x*y,
'div' : (x,y) => x/y, // careful with y=0 (no checks here)
'pwr' : (x,y) => x**y, // x to power of y
'deg' : (rad) => (rad * Math.PI / 360), // degrees from radians
'rad' : (deg) => (deg / Math.PI * 360), // radians from degrees
'pct' : (amt) => amt * 100, // form percentage
'bit' : (siz) => (acts.pwr(2,siz)-1).toString(2), // form bit-mask
'oct' : (dec) => dec.toString(8), // form octal
'hex' : (dec) => dec.toString(16), // form hexidecimal
'fmt' : (amt,size) => amt.toFixed(size), // number .toFixed(#) string
'cdt' : (dateInfo,locn='en-US') => dateInfo.toLocaleDateString(locn), // format US Date object
};
console.log(acts.inc(10)); // 11
console.log(acts.dec(15)); // 14
console.log(acts.mul(4,5)); // 20
console.log(acts.div(5,4)); // 1.25
console.log(acts.pwr(2,16)); // 65536
console.log(acts.deg(360)); // 3.14159...
console.log(acts.rad(Math.PI/2)); // 1.57079...
console.log(`${acts.pct(0.15)}%`); // 15%
console.log(`${acts.pct(acts.div(7,8))}%`); // 87.5%
console.log('0b'+acts.bit(8)); // 0b11111111
console.log('10.0 = 0o'+acts.oct(10),'octal'); // 0o12
console.log('0x'+acts.hex(65535)); // 0xffff
console.log(acts.fmt(Math.PI,2)); // 3.14
console.log(acts.fmt(Math.PI,4)); // 3.1416
console.log(Math.PI); // full precision PI
console.log('m/d/yyyy : ',acts.cdt(new Date())); // current date (m/d/year format) US
console.log('dd/mm/yyyy : ',acts.cdt(new Date(),'en-GB')); // date (dd/mm/year format) GB
// tests of binary range displays
console.log('\n ','----+'.repeat(6)+'--');
console.log('0b'+acts.bit(0)); // 0b0
console.log('0b'+acts.bit(0).padStart(8,'0')); // 0b00000000
console.log('0b'+acts.bit(16)); // 0b1111...1111 (length = 16 bits)
console.log('0b'+acts.bit(16).padStart(32,'0')); // 0b0111...1111
console.log('0b0'+acts.bit(31)); // 0b11111...11111 (length = 31 bits)
console.log('0b'+acts.bit(32).padStart(32,'0')); // 0b1111...1111 ( = 32 bits)
console.log('\n ','----+'.repeat(6)+'--');
console.log(`Dad's birthday: ${acts.cdt(new Date(1925,1,1))}`); // default US format
</script>
</body>
</html>
Additional comments are welcome.

Angularjs: how to detect min and max value of input numbers

I am trying to detect the minimum and maximum values of number type input field, so if the user increased the value, an ajax request get send, and so on for the max value.
Here is my code:
<input type="number" name="amount" id="amount" min="minNumber"
max="maxNumber" value="{{value['qty']}}"
data-product="{{value['id']}}"
ng-blur="isValid(true)"
ng-change="isValid(false)"
ng-model="level.num">
$scope.minNumber = 1,
$scope.maxNumber = 99,
$scope.addedToCart = false
$scope.isValid = function () {
if( ($scope.level.num < $scope.maxNumber) || ($scope.level.num > $scope.minNumber && blurMode)) {
$scope.tooMany = true;
$scope.level.num = $scope.minNumber;
}
};
You should not pass any parameter to your function from template, and use only ng-blur in your case no need of ng-change unless you want to check for each text change
ng-blur="isValid()"

Resources