Skip to content

Instantly share code, notes, and snippets.

@sannajammeh
Last active January 18, 2022 19:05
Show Gist options
  • Save sannajammeh/969e08958a4db79808543d223a20bb38 to your computer and use it in GitHub Desktop.
Save sannajammeh/969e08958a4db79808543d223a20bb38 to your computer and use it in GitHub Desktop.
JSON Stringify with number as decimal float value
const beginFloat = "~begin~float~";
const endFloat = "~end~float~";
type Config = Record<string, "float">;
export const stringifyWithFloats =
(config: Config = {}, decimals = 2) =>
(
inputValue: Record<string, any>,
inputReplacer?: (this: any, key: string, value: any) => any,
space?: string | number
) => {
const inputReplacerIsFunction = typeof inputReplacer === "function";
let isFirstIteration = true;
const jsonReplacer = (key: string, val: any) => {
if (isFirstIteration) {
isFirstIteration = false;
return inputReplacerIsFunction ? inputReplacer(key, val) : val;
}
let value: any;
if (inputReplacerIsFunction) {
value = inputReplacer(key, val);
} else if (Array.isArray(inputReplacer)) {
// remove the property if it is not included in the inputReplacer array
value = (inputReplacer as any).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: string, num: any) => {
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);
};
// Example usage
import fetch from "node-fetch";
import {stringifyWithFloats} from "./stringify-with-floats";
async function bootstrap() {
try {
const body = {
title: "Test SKU",
siteId: "_____",
externalId: "test_package",
type: "subscription",
price: [
{
offset: "0d",
amount: 50, // Formats to 50 in JS, 50.00 in stringifyWithFloats()
currency: "USD",
repeat: false,
},
{
offset: "30d",
amount: 50, // Formats to 50 in JS, 50.00 in stringifyWithFloats()
currency: "USD",
repeat: true,
},
],
};
const bodyWithFloats = stringifyWithFloats({
amount: "float", // Target amount key in provided object.
})(body);
const response = await fetch("https://api.example.com/sku", {
method: "POST",
headers: {
Authorization: "________",
"Content-Type": "application/json",
},
body: bodyWithFloats,
});
if (!response.ok) {
throw new Error(response.statusText);
}
const json = await response.json();
console.log(json);
} catch (error) {
console.log(error);
}
}
bootstrap();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment