I’m encountering an issue where my backend sends JSON data containing float numbers (e.g., 10.0, 20.0) to the UI side. However, upon receiving these numbers in the UI and logging them to the console, I observe that they are automatically converted to integers (10 and 20) instead of retaining their original float format. Strangely, numbers with a fractional part (e.g., 20.1) remain unchanged as 20.1.
I found the solution that I want. This is taken from stringify-with-floats npm library but modified to support any length of floats.
const stringifyWithFloats = (config = {}, decimals = 1) => {
const beginFloat = '__FLOAT__BEGIN__';
const endFloat = '__FLOAT__END__';
return (inputValue, inputReplacer, space) => {
const inputReplacerIsFunction = typeof inputReplacer === "function";
let isFirstIteration = true;
const jsonReplacer = (key, val) => {
if (isFirstIteration) {
isFirstIteration = false;
return inputReplacerIsFunction ? inputReplacer(key, val) : val;
}
let value;
if (inputReplacerIsFunction) {
value = inputReplacer(key, val);
} else if (Array.isArray(inputReplacer)) {
value = inputReplacer.indexOf(key) !== -1 ? val : undefined;
} else {
value = val;
}
const forceFloat =
config[key] === "float" &&
(value || value === 0) &&
typeof value === "number" &&
!value.toString().toLowerCase().includes("e");
return forceFloat ? `${beginFloat}${value}${endFloat}` : value;
};
const json = JSON.stringify(inputValue, jsonReplacer, space);
const regexReplacer = (match, num) => {
return num.includes(".") || Number.isNaN(num)
? Number.isNaN(num)
? num
: Number(num).toFixed(decimals)
: `${num}.${"0".repeat(decimals)}`;
};
const re = new RegExp(`"${beginFloat}(.+?)${endFloat}"`, "g");
return json.replace(re, regexReplacer);
};
};
// Test input
const testInput = {
foo: 10.0,
bar: {
baz: 20.0,
qux: {
value: 30.0
}
}
};
// Configure the stringifyWithFloats function
const customStringify = stringifyWithFloats({ foo: 'float', 'bar.baz': 'float' });
// Serialize the test input
const serializedJson = customStringify(testInput, null, 2);
// Output the serialized JSON
console.log(serializedJson);
Output:
{
"foo": 10.0,
"bar": {
"baz": 20,
"qux": {
"value": 30
}
}
}
So now the main issue and question. How to make this regex magic to handle nested objects and processes numbers as floats where required. AS you can see "foo" is shown correctly 10.0, but baz and value are not
2
Answers
I made a monster which gives me desired reuslt.This code provides a flexible way to serialize JavaScript objects into JSON strings while selectively formatting numeric values as floats based on a configurable set of rules (config). It handles nested objects recursively and ensures that numeric values are properly formatted using regular expressions after serialization.
in JavaScript, there is no
integer
andfloat
as two different types. any number is of typenumber
which may or may not contain decimals. the representation of the number will remove of tailing zeros of the decimal. so1.010100
will logged as1.01
,5.00
will logged as5
etc. (since it the same number).If in the UI you want to show it with decimal of x points, you can convert it to string, round to nearest decimal and add tailing zeros if need.
This can be done with the built-in function
x.toFixed(1)
Example: