23

I have a state as value: 10.00 and once I update it with some operation and add it to a <Text> the ".00" part gets trimmed off. If it was a value like 10.50, it'll be displayed as 10.5

This is a issue as I want to display currency values. How to handle this?

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
Nimila Hiranya
  • 4,842
  • 10
  • 35
  • 52
  • Does this answer your question? [Format number to always show 2 decimal places](https://stackoverflow.com/questions/6134039/format-number-to-always-show-2-decimal-places) – snakecharmerb Mar 02 '20 at 16:22

3 Answers3

72

Found the answer. To have the value with decimal values, use toFixed() method.

Example:

var value = 10;
value = value.toFixed(2);
this.setState({subTotal: value});

The output would be: 10.00

Nimila Hiranya
  • 4,842
  • 10
  • 35
  • 52
  • 2
    This will round your number to 2 decimal places. Depending on your use case it may be better to pass in a String instead of creating a String using toFixed. – John Shammas Dec 22 '15 at 16:41
  • 3
    or: this.setState({subTotal: value.toFixed(2)}); now your value will stay an number. – tibi Dec 07 '17 at 15:27
  • It is not working. it convert to string which is wrong for large calculations – Muhammad Ashfaq Mar 10 '20 at 07:01
  • 2
    The verified answer can return NaN if the user backspaces or adds a decimal into the Text Field before a number add the following to your function to prevent: `if (isNaN(value)) {return 0}` – Justin.Mathew Jan 20 '21 at 09:44
8

here is another solution you can also try, what i need is don't allow to enter more than 2 decimal digits (after decimal point) and also shouldn't allow more than two decimal points or any other character.

    ConTwoDecDigit=(digit)=>{
      return digit.indexOf(".")>0?
              digit.split(".").length>=2?
               digit.split(".")[0]+"."+digit.split(".")[1].substring(-1,2)
              : digit
             : digit
    }
    <TextInput 
       value={this.state.salary}
       onChangeText={value => this.setState({ salary: this.ConTwoDecDigit(value) })} 
      keyboardType={'decimal-pad'}
    />
Gaurav Vanani
  • 307
  • 5
  • 6
0

An alternative to the verified answer which catches more edge cases and allows string inputs. (defaults to 2dp but can be set by function caller)

export function normaliseValue (value: string, decimals = 2) {
  if (!value) {
    return ''
  }
  if (value === '.') {
    return value = '0.'
  }

  var regex = new RegExp(`^-?\\d+(?:\\.\\d{0,${decimals}})?`)
  const decimalsNumber = value.toString().match(regex)[0]
  const parsed = parseFloat(decimalsNumber).toFixed(2)
  if (isNaN(parsed)) {
    return '0'
  }
  return parsed
}

Example use in code:

  <TextInput
    label='Hours worked'
    placeholder='Hours worked'
    keyboardType='decimal-pad'
    value={String(values.hours)}
    onChangeText={(val) => setFieldValue('hours', normaliseValue(val, 3))}
  />
Justin.Mathew
  • 413
  • 5
  • 12