skip to Main Content

Since JSON.stringify does not support BigInts, a common suggestion is to patch toJSON into its prototype or use a replacer function to the likes of (k, v) => typeof v === 'bigint' ? v.toString() : v. The problem is, this stringifies BigInts as strings and not numbers { foo: 123n } becomes { "foo": "123" } instead of { "foo": 123 }.

I have a requirement to produce a payload for an API that expects a number, and that number can exceed the largest safe integer possible in JS. Is there any way to do that, besides building the string myself (or stripping out the quotes afterwards)?

2

Answers


  1. I would add some kind of unique token to the bigint string, then strip the quotes and token as a whole after stringify:

    const data = { foo: 123456789012345678901234567890n, bar: 1234567890 };
    
    const json = JSON.stringify(data, 
      (k, v) => typeof v === 'bigint' ? 'BIGINT_' + v : v
    ).replace(/"BIGINT_(d+)"/g, '$1');
    
    console.log(json);
    Login or Signup to reply.
  2. It depends on what you are looking for, Javascript cannot natively parse BigInt in JSON, but there are ways to work around that with altering JSON.parse() from the MDN BigInt Documentation.

    If your number is less than 2^53-1, then using Number(big_int) would be ideal. You can test for this with:

    var x = Number.MAX_SAFE_INTEGER // 2^53 - 1
    if (!isNaN(Number(x)) && Number.isSafeInteger(x)) {
      var number_int = Number(x)
    }
    

    If you really need to have the BigInt as in numeric form without the double quotes this is a quick and dirty way using string replacement. It replaces and stores BigInt values in a list before JSON.stringify() and then replacing the stub values with the numeric BigInt:

    var my_object = {
      key1: 24345354355435435454,
      key2: 24345354355435435454,
      key3: 53354545,
    };
    
    const big_json = json_obj => {
      var counter = 0;
      var key_holder = [];
      for (const [key, value] of Object.entries(my_object)) {
        if (!isNaN(Number(value)) && !Number.isSafeInteger(value)) {
          key_holder.push(value);
          my_object[key] = 'XXX' + String(counter);
          counter++;
        }
      }
      var json_string = JSON.stringify(my_object);
    
      for (var i = 0; i < counter; i++) {
        json_string = json_string.replace('"XXX' + String(i) + '"', key_holder[i]);
      }
      return json_string;
    };
    
    console.log(big_json(my_object))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search