An Interest In:
Web News this Week
- April 23, 2024
- April 22, 2024
- April 21, 2024
- April 20, 2024
- April 19, 2024
- April 18, 2024
- April 17, 2024
BigInt and JSON.stringify/JSON.parse
As of this writing, JavaScript's JSON.parse
cannot serialize the new JavaScript type BigInt
.
Imagine you have the following:
const data = { value1: BigInt(1231231231231231213), deep: { // NOTE the "n" at the end -- also a BigInt! value2: 848484848484848484884n, }}
If you try to just JSON.stringify(data)
you will get the error TypeError: Do not know how to serialize a BigInt
.
Serialization and Deserialization
It should be noted that how you choose to serialize your BigInts affects how you deserialize your BigInts. Generally, I serialize them by doing appending the "n" suffix to the end, similar to how we can declare a BigInt inline. (BigInt(0)
and 0n
yield the same result).
Serialization
Here we use JSON.stringify
's second argument (It's not always null
!!! haha.) which is the replacer
. The job of this function, if provided, is to determine how to serialize something based off of it's key and value. If the typeof
the value
is "bigint"
, we're going to convert it to a string, and tack an "n"
to the end.
// Serializationconst json = JSON.stringify(data, (key, value) => typeof value === "bigint" ? value.toString() + "n" : value);
The result: json
is:
{ "value1": "1231231231231231213n", "deep": { "value2": "848484848484848484884n", }}
Deserialization
In order to deserialize what we have above, we can use the second argument to JSON.parse()
. (I bet most people didn't know it has a second argument) This is called the reviver
, and it's job is to do basically the opposite of the replacer
above.
Here we'll test for the type and shape of the value to see that it matches a bunch of numbers followed by an "n"
.
// Deserializeconst backAgain = JSON.parse(json, (key, value) => { if (typeof value === "string" && /^\d+n$/.test(value)) { return BigInt(value.substr(0, value.length - 1)); } return value;});
Alternative serializations
This is all a little tricky, because you have to be sure that none of your other data is in a format where it's a bunch of numbers and an "n"
at the end. If it is, you need to change your serialization strategy. For example, perhaps you serialize to BigInt::1231232123
and deserialize the same at the other side, such as the example below:
// Serializeconst json = JSON.stringify(data, (key, value) => typeof value === "bigint" ? `BIGINT::${value}` : value);// Deserializeconst backAgain = JSON.parse(json, (key, value) => { if (typeof value === "string" && value.startsWith('BIGINT::')) { return BigInt(value.substr(8)); } return value;});
The choice is really up to you, just as long as you have the tools to do it.
Original Link: https://dev.to/benlesh/bigint-and-json-stringify-json-parse-2m8p
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To