w

API Reference

Technical documentation for developers who want to integrate or extend the JSON to CSV converter functionality.

Browser API Usage

Clipboard API

The tool uses the modern Clipboard API for copy operations:

// Copy text to clipboard
async function copyToClipboard(text) {
  try {
    await navigator.clipboard.writeText(text);
    console.log('Text copied to clipboard');
  } catch (error) {
    console.error('Failed to copy text: ', error);
  }
}

Browser Support:

  • Chrome 66+
  • Firefox 63+
  • Safari 13.1+
  • Edge 79+

File Download API

CSV files are downloaded using the Blob API:

// Download CSV file
function downloadCSV(csvContent, filename) {
  const blob = new Blob([csvContent], {
    type: 'text/csv;charset=utf-8',
  });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}

Data Processing Functions

JSON Validation

// Validate JSON string
function validateJSON(jsonString) {
  try {
    const parsed = JSON.parse(jsonString);
    return { valid: true, data: parsed };
  } catch (error) {
    return { valid: false, error: error.message };
  }
}

CSV Conversion Logic

// Convert JSON array to CSV
function jsonToCSV(jsonData, options = {}) {
  const { delimiter = ',', includeHeaders = true, escapeQuotes = true } = options;

  if (!Array.isArray(jsonData) || jsonData.length === 0) {
    return '';
  }

  // Get all unique keys
  const allKeys = new Set();
  jsonData.forEach((item) => {
    if (typeof item === 'object' && item !== null) {
      Object.keys(item).forEach((key) => allKeys.add(key));
    }
  });

  const keys = Array.from(allKeys);
  let csv = '';

  // Add headers
  if (includeHeaders) {
    csv += keys.map((key) => escapeCSVValue(key, delimiter, escapeQuotes)).join(delimiter) + '\n';
  }

  // Add data rows
  jsonData.forEach((item) => {
    if (typeof item === 'object' && item !== null) {
      const row = keys.map((key) => {
        const value = item[key];
        return escapeCSVValue(value !== undefined ? String(value) : '', delimiter, escapeQuotes);
      });
      csv += row.join(delimiter) + '\n';
    }
  });

  return csv;
}

CSV Value Escaping

// Escape CSV values
function escapeCSVValue(value, delimiter, escapeQuotes) {
  if (!escapeQuotes) {
    return value;
  }

  // If value contains delimiter, newline, or quotes, wrap in quotes
  if (value.includes(delimiter) || value.includes('\n') || value.includes('"')) {
    // Escape quotes: replace " with ""
    return `"${value.replace(/"/g, '""')}"`;
  }

  return value;
}

Configuration Options

Conversion Options Interface

interface ConversionOptions {
  delimiter: ',' | ';' | '\t' | '|';
  encoding: 'utf-8' | 'utf-16' | 'gbk';
  includeHeaders: boolean;
  escapeQuotes: boolean;
}

Default Configuration

const defaultOptions = {
  delimiter: ',',
  encoding: 'utf-8',
  includeHeaders: true,
  escapeQuotes: true,
};

Data Structures

History Record Interface

interface HistoryRecord {
  id: string;
  input: string;
  inputPreview: string;
  output: string;
  delimiter: string;
  encoding: string;
  includeHeaders: boolean;
  escapeQuotes: boolean;
  rows: number;
  columns: number;
  timestamp: string;
  timestampMs: number;
}

Statistics Interface

interface ConversionStats {
  rows: number;
  columns: number;
  size: string; // Formatted file size
}

Error Handling

Error Types

enum ConversionError {
  INVALID_JSON = 'INVALID_JSON',
  CONVERSION_FAILED = 'CONVERSION_FAILED',
  EMPTY_DATA = 'EMPTY_DATA',
  UNSUPPORTED_FORMAT = 'UNSUPPORTED_FORMAT',
}

Error Handling Function

// Handle conversion errors
function handleConversionError(error, jsonInput) {
  switch (error.type) {
    case 'INVALID_JSON':
      return {
        message: 'Invalid JSON format. Please check your input.',
        field: 'input',
        severity: 'error',
      };
    case 'CONVERSION_FAILED':
      return {
        message: 'Failed to convert JSON to CSV. Please check your data.',
        field: 'output',
        severity: 'error',
      };
    default:
      return {
        message: 'An unexpected error occurred.',
        field: 'general',
        severity: 'error',
      };
  }
}

Performance Considerations

Large Dataset Handling

// Process large datasets in chunks
function processLargeDataset(jsonData, chunkSize = 1000) {
  const chunks = [];
  for (let i = 0; i < jsonData.length; i += chunkSize) {
    chunks.push(jsonData.slice(i, i + chunkSize));
  }

  return chunks.map((chunk) => jsonToCSV(chunk));
}

Memory Management

// Monitor memory usage
function getMemoryUsage() {
  if (performance.memory) {
    return {
      used: performance.memory.usedJSHeapSize,
      total: performance.memory.totalJSHeapSize,
      limit: performance.memory.jsHeapSizeLimit,
    };
  }
  return null;
}

Browser Compatibility

Feature Detection

// Check browser capabilities
function checkBrowserSupport() {
  return {
    clipboardAPI: !!navigator.clipboard,
    blobAPI: !!window.Blob,
    fileAPI: !!window.File,
    localStorage: !!window.localStorage,
    jsonSupport: !!JSON.parse,
  };
}

Polyfills

For older browsers, consider these polyfills:

// Clipboard API polyfill
if (!navigator.clipboard) {
  navigator.clipboard = {
    writeText: function (text) {
      return new Promise((resolve, reject) => {
        const textArea = document.createElement('textarea');
        textArea.value = text;
        document.body.appendChild(textArea);
        textArea.select();
        try {
          document.execCommand('copy');
          resolve();
        } catch (error) {
          reject(error);
        }
        document.body.removeChild(textArea);
      });
    },
  };
}

Integration Examples

React Component Integration

import React, { useState, useCallback } from 'react';

function JSONToCSVConverter() {
  const [jsonInput, setJsonInput] = useState('');
  const [csvOutput, setCsvOutput] = useState('');
  const [options, setOptions] = useState(defaultOptions);

  const convertToCSV = useCallback(() => {
    try {
      const jsonData = JSON.parse(jsonInput);
      const csv = jsonToCSV(jsonData, options);
      setCsvOutput(csv);
    } catch (error) {
      console.error('Conversion failed:', error);
    }
  }, [jsonInput, options]);

  return (
    <div>
      <textarea
        value={jsonInput}
        onChange={(e) => setJsonInput(e.target.value)}
        placeholder="Enter JSON data..."
      />
      <button onClick={convertToCSV}>Convert</button>
      <textarea value={csvOutput} readOnly placeholder="CSV output will appear here..." />
    </div>
  );
}

Vue.js Integration

<template>
  <div class="json-to-csv-converter">
    <textarea v-model="jsonInput" placeholder="Enter JSON data..." @input="validateAndConvert" />
    <div class="options">
      <select v-model="options.delimiter">
        <option value=",">Comma (,)</option>
        <option value=";">Semicolon (;)</option>
        <option value="\t">Tab</option>
        <option value="|">Pipe (|)</option>
      </select>
    </div>
    <textarea :value="csvOutput" readonly placeholder="CSV output will appear here..." />
  </div>
</template>

<script>
export default {
  data() {
    return {
      jsonInput: '',
      csvOutput: '',
      options: {
        delimiter: ',',
        includeHeaders: true,
        escapeQuotes: true,
      },
    };
  },
  methods: {
    validateAndConvert() {
      try {
        const jsonData = JSON.parse(this.jsonInput);
        this.csvOutput = this.jsonToCSV(jsonData, this.options);
      } catch (error) {
        this.csvOutput = '';
      }
    },
    jsonToCSV(jsonData, options) {
      // Implementation here
    },
  },
};
</script>

Testing

Unit Test Examples

// Jest test examples
describe('JSON to CSV Converter', () => {
  test('converts simple array to CSV', () => {
    const input = [
      { name: 'John', age: 30 },
      { name: 'Jane', age: 25 },
    ];
    const expected = 'name,age\nJohn,30\nJane,25\n';
    expect(jsonToCSV(input)).toBe(expected);
  });

  test('handles special characters', () => {
    const input = [{ name: 'Smith, John', quote: 'He said "Hello"' }];
    const expected = 'name,quote\n"Smith, John","He said ""Hello"""\n';
    expect(jsonToCSV(input)).toBe(expected);
  });

  test('validates JSON input', () => {
    const invalidJson = '{ name: "John" }'; // Missing quotes
    const result = validateJSON(invalidJson);
    expect(result.valid).toBe(false);
  });
});
Was this page helpful?