Skip to content

Expose JSON parse reviver #5924

@basememara

Description

@basememara

Is your feature request related to a problem? Please describe.

In my custom Axios instance, I would like to provide my own reviver function to JSON.parse to deserialize dates. I could use a transformResponse but I do not want to bypass the default behaviour the existing implementation.

Describe the solution you'd like

Instead, I'm hoping to optionally provide my own reviver that is exposed as a default:

// Axios internal default object
const defaults = {
  transitional: transitionalDefaults,
  adapter: ['xhr', 'http'],
  parseReviver: null,
  transformResponse: [function transformResponse(data) {
    ...
    try {
        return JSON.parse(data, this.parseReviver);
    } catch (e) {
        ...
    }
  },
  ...
}

// My instance
const instance = axios.create({
  parseReviver: (key, value) => /* custom implementation */
});

Describe alternatives you've considered

Override the transformResponse but I'm ignoring many essential default implementations and validations.

Also tried providing my own response interceptor, but it's too late by then and have to recursively walk the object tree to conditionally convert each property which is heavy and error prone:

const convertDateProperties = <T>(data: T) => {
  if (typeof data === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(data)) {
    return new Date(data) as unknown as T;
  }

  if (Array.isArray(data)) {
    return data.map((item) => convertDateProperties(item)) as unknown as T;
  }

  if (data instanceof Object) {
    return Object.keys(data).reduce((acc, key) => {
      acc[key] = convertDateProperties(data[key]);
      return acc;
    }, {} as T);
  }

  return data;
};

instance.interceptors.response.use(
  (response) => {
    if (response.data) {
      response.data = convertDateProperties(response.data);
    }
    return response;
  },
  (error) => Promise.reject(error)
);

Additional context/Screenshots

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions