Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 4, 2021 06:25 pm GMT

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,  }}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

The result: json is:

{  "value1": "1231231231231231213n",  "deep": {    "value2": "848484848484848484884n",  }}
Enter fullscreen mode Exit fullscreen mode

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;});
Enter fullscreen mode Exit fullscreen mode

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;});
Enter fullscreen mode Exit fullscreen mode

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

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To