Handle BigInt Data on JavaScript

Handle BigInt Data on JavaScript

Handle BigInt Data on Vue3

Β·

3 min read

Error

Meet Error

I meet the below error when I use axios with bigint data.

TypeError: Do not know how to serialize a BigInt

Why did this error appear in the console?

I investigated why this error occurred.

The information was found on JSON stringify #execptions.

JSON stringify method #Exceptions

Why can't JSON.stringify serialize BigInt?

Because BigInt values are not supported by the JSON specification.

In JSON, values must be one of the following data types:

  • a string

  • a number

  • an object (JSON object)

  • an array

  • a boolean

  • null

JSON values cannot be one of the following data types:

  • a function

  • a date

  • undefined

Since BigInt is not one of these valid types, JSON.stringify will throw a TypeError when attempting to serialize a BigInt value.

How?

I found 3 solutions to handle BigInt Data.

  1. Install json-bigint package

     import JSONbig from 'json-bigint';
     import axios from 'axios';
    
     const axiosInstance = axios.create({
       transformResponse: [function (data) {
         try {
           return JSONbig.parse(data);
         } catch (error) {
           return data;
         }
       }]
     });
    
  2. Use Blob response type on configuration option in your Axios request

     axios.get('/api/data', {
       responseType: 'blob'
     })
     .then(response => {
       response.data.text()
       .then(data => {
         const parsedData = JSON.parse(data, (key, value) => {
           if (typeof value === 'string' && /^\d+$/.test(value)) {
             return BigInt(value);
           }
           return value;
         });
         console.log(parsedData); // This will now return BigInt values as well
       })
     })
     .catch(error => {
       console.log(error);
     });
    

    Or if you are using an Axios instance, you can set a custom transformRequest or transformResponse function to modify the request data before it is sent.

     import axios, { AxiosInstance } from 'axios';
    
     const api: AxiosInstance = axios.create({
       baseURL: 'http://example.com/api',
       transformRequest: (data, headers) => {
         if (data && typeof data === 'object') {
           Object.keys(data).forEach(key => {
             const value = data[key];
             if (typeof value === 'bigint') {
               data[key] = value.toString(); // Convert BigInt to string
             }
           });
         }
         return JSON.stringify(data);
       }
     });
    
     const payload = {
       id: 12345678901234567890n // BigInt value
     };
    
     api.post('/data', payload)
       .then(response => {
         console.log(response.data);
       })
       .catch(error => {
         console.log(error);
       });
    
  3. Change BigInt Prototype

    You can make a custom toJSON method to the BigInt prototype and make it available globally in your Vue 3 application, you can add the following code to your main.ts file.

     // main.ts
    
     const BigIntProto = BigInt.prototype as any;
     BigIntProto.toJSON = function () {
       // return Number(this);
       return this.toString();
     };
    
     app.config.globalProperties.$BigInt = BigInt;
    

    This code adds a custom toJSON method to the BigInt prototype that simply returns the numeric value of the BigInt as a Number or string.

    It then sets the BigInt constructor as a global property of the Vue application so that you can access it in your components using this.$BigInt.

    With this approach, you can simply use JSON.stringify() to convert objects with BigInt properties to JSON, and the BigInt values will be automatically converted to numbers.

I solve this error with 3rd solution.

Conclusion

I'm not sure which one is better.

In my case, modifies the behavior of the BigInt type globally, which could cause unexpected issues or conflicts with other libraries or parts of the application.

So I recommend using the solution that fits your situation best.

Thank you for reading.

Did you find this article valuable?

Support JaeChan Lee by becoming a sponsor. Any amount is appreciated!

Β