skip to Main Content

I’m building a small project with a POSTR request which expect multiple fields with 2 floats.

My backend expect "." as the decimal separator. However my audience is French and will most probably use "," as decimal separator. Since I don’t want to add a small note on my frontend so I tried below code updates to make sure my backend get the dot no matter what is used by the user – without success I’m afraid…

Any ideas ? Thank you !

const dotedSize = size.replace(",", ".");
const dotedWeight = weight.replace(",", ".");

POST request:

const response = await apiInstance.post(`${apiBaseUrl}/create_vote`, {
          first_name,
          last_name,
          gender,
          size: parseFloat(dotedSize),
          weight: parseFloat(dotedWeight),
          birthday: dateTimeToSend,
        }

3

Answers


  1. I suggest you to do it the other way around, i.e. to work with numbers everywhere (including your backend) and only format it when displaying the values to the user.

    To format a number accordingly you can use Number.prototype.toLocaleString() (src):

    const val = 1234567.89
    
    // use the user's configured locale
    console.log(val.toLocaleString()) // outputs "1,234,567.89" in my case
    
    // use a specific locale
    console.log(val.toLocaleString('fr-FR')) // outputs "1 234 567,89"
    
    Login or Signup to reply.
  2. If you are using <input type="number" />, I don’t think you need to manually parse/convert float number based on the user’s locale.

    When the element’s value is accessed, the number should be converted to one with dot as decimal separator.

    enter image description here

    Here’s a jsfiddle to try out: https://jsfiddle.net/rg2wvkn3/. You can change your locale settings in Chrome by doing: Settings > Languages > some other language. I had changed to French/France, hence, the console logged "fr-FR".


    But if you’re not using input with number type,

    You can first check user’s locale using Intl.Numberformat to get the user’s locale then convert the string accordingly.

    const userLocale = navigator.language
    const decimalSep = new Intl.NumberFormat(userLocale).format(0.1) === '0,1' ? ',' : '.'
    
    let input = "9999,999"
    if(decimalSep === ',') {
      input = input.replace(',', '.')
    }
    
    const results = parseFloat(input)
       
    
    Login or Signup to reply.
  3. You could detect if the decimal separator is a comma. If it is, just reverse the thousands and decimal separators, remove the thousands separator and any other non-numeric characters, and convert the string to a number.

    // Parse string values
    console.log(parseNumberInput("€9.999.999,999", 'fr-ca'));
    console.log(parseNumberInput("$9,999,999.999"));
    
    // Parse input value
    console.log(parseNumberInput(document.getElementById('amount').value, 'fr-ca'));
    
    // No parsing needed
    console.log(document.getElementById('amount2').valueAsNumber);
    
    function parseNumberInput(input, locale) {
      const userLocale = locale ?? navigator.language;
      const usesCommaSeparator = new Intl.NumberFormat(userLocale).format(0.1) === '0,1';
      const decimalSep = usesCommaSeparator ? /,/g : /./g;
      const thousandsSep = usesCommaSeparator ? /./g : /,/g;
      return Number(input.replace(thousandsSep, '').replace(decimalSep, '.').replace(/[^d.]/g, ''));
    }
    <input id="amount" type="text" value="$9.999.999,999" />
    <input id="amount2" type="number" value="9999999.999" />
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search