59

How do I take a number like 10000 and have it output as $10,000.00? I even had a problem with String.format(...) with a Not a function error.

I followed numerous articles, all incomplete and none working. I don't need full internationalization, just the ability to format a number

Vy Do
  • 46,709
  • 59
  • 215
  • 313
Choco
  • 1,189
  • 1
  • 14
  • 29

12 Answers12

58

You can use toFixed method for showing 2 decimal point.

let num = 1000; 
console.log(num.toFixed(2)); // 1000.00

And you can use Regex like this

function currencyFormat(num) {
   return '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
}
console.log(currencyFormat(2665)); // $2,665.00
Ray
  • 2,713
  • 3
  • 29
  • 61
Robin
  • 4,902
  • 2
  • 27
  • 43
  • The second way doesn't work. It prints 1665, not 2665. – romin21 Apr 06 '20 at 12:04
  • @romin21 it works fine. Do you try `Run code snippet` ? In my case it print $2,665.00 – Robin Apr 07 '20 at 02:51
  • on React Native it print 1665. Could be a problem with the engine behind React Native. – romin21 Apr 07 '20 at 09:19
  • 1
    The currency does not always comes before the value, it depends on the language – ofer2980 Sep 02 '20 at 07:48
  • @ofer2980 then why not modify what you want ? Its very simple, you need currency at the last - add it at the last. – Robin Sep 02 '20 at 10:09
  • Yes, but it depends on the language – how can you tell where it comes for each and every language? I believe using the Intl.NumberFormatter, which gets the locale as an input, is a better solution – ofer2980 Sep 02 '20 at 21:49
  • `8364`not working for € – Mo. Jan 12 '22 at 11:51
  • @Mo. It works, i tested with `8364`. Its a js snippet, so it should work for any number. Please check your code – Robin Jan 13 '22 at 16:34
  • @Robin fixed with `new Intl.NumberFormat('en-GB', {`. Any way thanks for your response – Mo. Jan 13 '22 at 16:58
  • @Robin But for this to work we need to have input type="text" which then allows even alphabet to be entered inside the input field. Is there any way that we can perform the same task by only allowing only numbers/decimal. – Red Cloud Mar 10 '22 at 16:49
44

You can use this library react-number-format. It has these features

  1. Prefix, suffix and thousand separator.
  2. Custom format pattern.
  3. Masking.
  4. Custom formatting handler.
  5. Format number in an input or format as a simple text

Sample usage

<NumericFormat value={2456981.toFixed(2)} displayType={'text'} thousandSeparator={true} prefix={'$'} />

Output : $2,456,981.00

Community
  • 1
  • 1
Masuk Helal Anik
  • 2,155
  • 21
  • 29
31

Edit: Sorry -this is a React.js solution - not React Native. None of the above worked for me ... but this chap had the right idea / solution https://medium.com/@nidhinkumar/react-js-number-format-and-styling-a1a6e211e629

const numberFormat = (value) =>
  new Intl.NumberFormat('en-IN', {
    style: 'currency',
    currency: 'INR'
  }).format(value);

numberFormat(50000); //output as ₹ 50,000.00
numberFormat(10000); //output as ₹ 10,000.00
Murray
  • 515
  • 4
  • 11
  • 4
    Can you make sure this solution works in Android? Last time I used react native, the "Intl" object brings crash to my android release. – Asad S Jun 19 '20 at 03:47
  • Anyone succeed in making this work in React Native? – Nate Aug 11 '20 at 13:48
  • @AsadS /** * The preferred build flavor of JavaScriptCore. * * For example, to use the international variant, you can use: * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ – Diego Molina Sep 28 '20 at 19:44
  • 1
    In brazilian currency: `const numberFormat = (value) => new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value);` – Leffa Aug 23 '22 at 15:47
12

To avoid using libraries, you can use the following code

const defaultOptions = {
  significantDigits: 2,
  thousandsSeparator: ',',
  decimalSeparator: '.',
  symbol: '$'
}

const currencyFormatter = (value, options) => {
  if (typeof value !== 'number') value = 0.0
  options = { ...defaultOptions, ...options }
  value = value.toFixed(options.significantDigits)

  const [currency, decimal] = value.split('.')
  return `${options.symbol} ${currency.replace(
    /\B(?=(\d{3})+(?!\d))/g,
    options.thousandsSeparator
  )}${options.decimalSeparator}${decimal}`
}
Gabriel Brito
  • 1,003
  • 2
  • 16
  • 26
5

The fastest way is to use react-number-format, as stated above, but don't forget the renderText prop so that React Native don't throw rendering error.

Follow this step:

  1. Install. Use this command:
npm i react-number-format
  1. Use it in your React Native app like this:
import React from 'react';
import NumberFormat from 'react-number-format';

export function ReactNativeNumberFormat({ value }) {
  return (
    <NumberFormat
      value={value}
      displayType={'text'}
      thousandSeparator={true}
      prefix={'$'}
      renderText={formattedValue => <Text>{formattedValue}</Text>} // <--- Don't forget this!
    />
  );
}

It's working good. As you can see, I ended up creating my custom component that accept value as prop so I can use it everywhere I need it. Just like this:

  <View>
    <ReactNativeNumberFormat value={530000} />
  </View>

Hope can be useful.

PS: This is my reference => https://github.com/s-yadav/react-number-format/issues/17#issuecomment-395187806.

Asad S
  • 2,096
  • 2
  • 11
  • 9
5

Use toLocaleString native React function:

  const formatNumber = (q) => {
    return q.toLocaleString('en-US', {
        style: 'currency',
        currency: 'USD'
    })
   } 
Juan Banzer
  • 59
  • 1
  • 1
1

Versions

  • TypeScript: 4.7.2
  • React: 18.2.0

Component: Currency.tsx

import React from "react";

interface IProps {
  price: number;
}

const Currency: React.FC<IProps> = ({ price }) => {
  return (
    <>
    {Intl.NumberFormat('en-US', {
      style: 'currency', 
      currency: 'USD' // Change this
      }).format(price)}
    </>
  );
}

export default Currency;

In your page component

<Currency price={10000} />

Result

$ 10 000,00

0

I wrote the following number format utility recently which can be used in OP's case as well as others. It should hopefully be fairly straightforward to amend it to cover other cases (I expect most would like to change my default values for example).

type NumberFormatProps = {
  value: number;
  thousandSeparator?: string;
  decimalSeparator?: string;
  significantDigits?: number;
  showTrailingZeros?: boolean;
  symbol?: '$' | 'kr.' | '%'; // Add other symbols as needed
  showSymbol?: boolean;
  symbolPosition?: 'before' | 'after';
  showSymbolSpace?: boolean;
};


/**
 * Formats a number. Supports changing symbol, thousand and decimal separators and more (see props).
 * @param value The value to format
 * @param thousandSeparator The separator to use between thousands
 * @param decimalSeparator The separator to use before decimals
 * @param significantDigits The number of significant digits to show
 * @param showTrailingZeros Whether to show trailing zeros for significant digits (i.e. 1,00 if significant digits is 2)
 * @param symbol The  symbol to use
 * @param showSymbol Whether to show the symbol
 * @param symbolPosition Whether to show the symbol before or after the value
 * @param showSymbolSpace Whether to show a space between the  symbol and the value
 * @returns
 */
export const getFormattedNumber = ({
  value,
  thousandSeparator = '.',
  decimalSeparator = ',',
  significantDigits = 0,
  showTrailingZeros = false,
  symbol = 'kr.',
  showSymbol = true,
  symbolPosition = 'after',
  showSymbolSpace = true,
}: NumberFormatProps) => {
  const significantDigitsExponent = 10 ** significantDigits;
  const valueWithSignificantDigits = showTrailingZeros
    ? // If significant digits is 2 then this is e.g. 1.00, 1.10, 1.11
      value.toFixed(significantDigits)
    : // If significant digits is 2 then this is e.g. 1, 1.1, 1.11
      `${Math.round((value + Number.EPSILON) * significantDigitsExponent) / significantDigitsExponent}`;

  // Split the value into the parts before and after the decimal point
  const [integerPart, fractionalPart] = valueWithSignificantDigits.toString().split('.');
  // Replace thousand separator in integer part
  const formattedIntegerPart = `${integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator)}`;
  // Add decimal separator and fractional part if needed
  const formattedValue = fractionalPart
    ? `${formattedIntegerPart}${decimalSeparator}${fractionalPart}`
    : formattedIntegerPart;

  // Add symbol
  if (showSymbol && Boolean(symbol)) {
    const formattedValueWithSymbol =
      symbolPosition === 'after' ? `${formattedValue} ${symbol}` : `${symbol} ${formattedValue}`;
    return showSymbolSpace ? formattedValueWithSymbol : formattedValueWithSymbol.replace(' ', '');
  }

  return formattedValue;
};

In OP's case this would be called like so:

getFormattedNumber({
  value: 10000,
  thousandSeparator: ',',
  decimalSeparator: '.',
  symbol: "$",
  showSymbolSpace: false,
  symbolPosition: 'before',
  significantDigits: 2,
  showTrailingZeros: true
})
jorundur
  • 550
  • 1
  • 5
  • 19
0
export const CurrencyFormatter = (number, options) => {
  const defaultOptions = {
    significantDigits: 2,
    thousandsSeparator: ",",
    decimalSeparator: ".",
    symbol: "$",
  };

  const currencyFormatter = (value, options) => {
    if (typeof value !== "number") value = 0.0;
    options = { ...defaultOptions, ...options };
    value = value.toFixed(options.significantDigits);

    let valueFormatted;

    if (options.significantDigits == 0) {
      const [currency] = value.split(".");
      valueFormatted = `${options.symbol}${currency.replace(
        /\B(?=(\d{3})+(?!\d))/g,
        newOptions.thousandsSeparator
      )}`;
    } else {
      const [currency, decimal] = value.split(".");
      valueFormatted = `${options.symbol}${currency.replace(
        /\B(?=(\d{3})+(?!\d))/g,
        options.thousandsSeparator
      )}${options.decimalSeparator}${decimal}`;
    }

    return valueFormatted;
  };

  return currencyFormatter(number, options);
};
0

how are you :)! You also have this option to make a javscript function and with that function show the 'numeric' value that you want to show with the following format ($10,000.00):

function currencyFormat(num) {
    const numericValue = Number(num); // Convert the value to number
         if (isNaN(numericValue)) {
             // If not a valid number, return an empty string or the original value
             return "";
         } else {
             return "$" + numericValue.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"); // And this would be the function
         }
     }

You can also add this in each .js or .tsx file that you need or also to not add the entire function, you can create a file in the root path that is of type context with 'createContext()' you can guide yourself more here 'Guide to using 'createContext()'', with that you will only have to get the function from that context file and it is less code to render in your .js or .tsx files. I hope I've helped :)

henZzz
  • 11
  • 1
0

For Indian currency use, To more Follow the link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat

 const number= 123.45679;
const currencyFormatter = Intl.NumberFormat("en-IN", {
  style: "currency",
  currency: "INR",
  maximumFractionDigits: 3,
});

currencyFormatter .format(number);

Others use like the Intl.NumberFormat object

 console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// Expected output: "123.456,79 €"

// The Japanese yen doesn't use a minor unit

console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));

// Expected output: "¥123,457"

Apurv
  • 21
  • 5
-1

could be achieved as shown below, and you could also remove trailing 00 at the end if there is no decimals

      costing= () => {
        const cost= 1478.90 + 940;
        return parseFloat(cost).toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
      }
vincent O
  • 518
  • 8
  • 33