I am just here to see if anyone knows what may be going on here in my React application. So I am doing some validation in my input field and it has to do with some numbers. I am doing the validation here:
const handleAmount = (value) => {
const formattedInput = value.match(/^\d+\.?\d{0,20}/);
const minimumPurchase = 5;
if (Number(formattedInput) < Number(minimumPurchase)) {
setIsInvalidAmount(true);
} else {
setIsInvalidAmount(false);
}
setAmount(formattedInput);
};
And here is where the handler is being attached to:
<TextField
className={classes.textField}
type="number"
onChange={e => handleAmount(e.target.value)}
value={amount}
error={isInvalidAmount} />
I also have a button to autofill the amount of items to purchase:
function autoFillAmountTotal(selectedItem) {
if (availableBalance.match(/^\d+\.?\d{0,8}/) != null) {
const netBalance = selectedItem.amountOfItems - selectedItems.backlogged;
setAmount(netBalance);
// This causes an error with value.match from the handleAmount function
handleAmount(netBalance);
// This renders fine, but I need it to do the calculation before passing value
handleAmount(selectedItem.amountOfItems);
}
}
function getAvailableText() {
if (selectedItem) {
return (
<React.Fragment>
<div className={classes.availableAmount}>(Number of items to buy: <Link className={classes.available} variant="text" onClick={() => autoFillAmountTotal(selectedItem.amountOfItems - selectedItem.backlogged)}>{items.amountOfItems}</Link>)</div>
</React.Fragment>
); }
This autofilled amount needs to do some validation, and it needs to have an onChange event, so I put the handleAmount function(which is an onChange handler attached to textfield) inside the autofill function. Otherwise, there wouldn't be any validation done in there.
The issue is when I try to pass an amount inside after calculation in the handleAmount() function when it is called inside another function, it gives an error.
Well, String.prototype.match() accepts only strings. You may convert your value into a string or check it with basic if statements like:
if (value > 0 && value < 20) {
...
}
Sorry, I'm not the RegEx expert, but from what I can see is that you check your value if it's a number and that it is between 0 and 20.
UPDATE:
I refactored the code a bit and added comments, where I didn't know where certain values come from.
function autoFillAmountTotal(selectedItem) {
// I don't know where the value availableBalance comes from
// I guess from a state. Please check if it is a string or convert it to one, like I show in solution number 1.
if ((availableBalance.match(/^\d+\.?\d{0,8}/)||[]).length) {
const netBalance = selectedItem.amountOfItems -
selectedItems.backlogged;
setAmount(netBalance);
// This causes an error with value.match from the handleAmount function
handleAmount(netBalance);
// This renders fine, but I need it to do the calculation before passing value
handleAmount(selectedItem.amountOfItems);
}
}
And then your handleAmount function solution number 1:
const handleAmount = (value) => {
// convert your value to a string before you match it with a regEx
const valueString = value.toString();
const formattedInput = valueString.match(/^\d+\.?\d{0,20}/);
const minimumPurchase = 5;
if (Number(formattedInput) < Number(minimumPurchase)) {
setIsInvalidAmount(true);
} else {
setIsInvalidAmount(false);
}
setAmount(formattedInput);
};
Here your handleAmount function preferred solution number 2. Your RegEx checks if you have any float number with at most 20 followed points after the decimal point.
// somewhere on top of your document, put your constants preferably like this
const MINIMUM_PURCHASE = 5;
const handleAmount = (value) => {
// convert float to number without decimals.
// I guess, this is not even needed, because the selectedItem value should be already a number without decimals
const formattedInput = Number(Math.floor(value));
if (formattedInput < MINIMUM_PURCHASE) {
setIsInvalidAmount(true);
} else {
setIsInvalidAmount(false);
}
setAmount(formattedInput);
};