How to Build a JSON Diff Tool by JavaScript

By hientd, at: July 6, 2023, 11 p.m.

Estimated Reading Time: 11 min read

How to Build a JSON Diff Tool by JavaScript
How to Build a JSON Diff Tool by JavaScript

How to Build a JSON Diff Tool by JavaScript

JSON (JavaScript Object Notation) is a widely used data format for storing and exchanging information - a simple and lightweight way to represent data structures. Comparing JSON objects and identifying their differences can be a valuable task in various scenarios. In this article, we will explore how to build a JSON diff tool using JavaScript. We'll cover important concepts, edge cases, tips and tricks, and best practices along the way.

 

1. Introduction to JSON


What is JSON?

JSON is a text-based data format that is easy for humans to read and write. It is based on a subset of the JavaScript Programming Language and is often used to transmit data between a server and a web application, as an alternative to XML.


JSON Syntax

JSON syntax consists of key-value pairs enclosed in curly braces ({}) and separated by commas. Keys are always strings, and values can be strings, numbers, booleans, arrays, objects, or null.


JSON Data Types

JSON supports several data types, including:

  • String: A sequence of characters enclosed in double quotes.
  • Number: An integer or a floating-point number.
  • Boolean: Either true or false.
  • Array: An ordered list of values enclosed in square brackets ([]).
  • Object: An unordered collection of key-value pairs enclosed in curly braces ({}).
  • Null: A special value representing null or absence of a value.

JSON Object

 

2. What is a JSON Diff Tool?


Purpose and Benefits

A JSON diff tool is a tool that compares two JSON objects and highlights their differences. It helps in identifying changes, additions, and deletions between two JSON structures. JSON diff tools are particularly useful in scenarios such as:

  • Version control systems: changes in JSON configuration files need to be tracked.
  • API development and testing: changes in API responses or request payloads need to be detected.
  • Data synchronization and merging operations: differences between two datasets need to be reconciled.

By using a JSON diff tool, developers and data analysts can easily visualize and understand the changes made to JSON data, making troubleshooting and debugging tasks more efficient.


Use Cases

Some common use cases for a JSON diff tool include:

  • Comparing JSON configuration files to detect changes between different versions.
  • Validating API responses by comparing them with expected JSON structures.
  • Identifying differences in large datasets during data integration or migration processes.
  • Analyzing changes made to JSON-based data models or schema definitions.

 

3. Building a JSON Diff Tool with JavaScript

Now let's dive into the process of building a JSON diff tool using JavaScript. We'll break it down into several steps to make the development process more manageable.


Step 1: Setting Up the HTML Structure

To create a user interface for our JSON diff tool, we need to set up the HTML structure. We can create a simple webpage with two text areas where users can input JSON objects for comparison.

JSON diff

 

The HTML content would be

JSON DIFF HTML

 

Step 2: Setting Up the JS content

To create a user interface for our JSON diff tool, we need to set up the HTML structure. We can create a simple webpage with two text areas where users can input JSON objects for comparison.

function showSuccessAlert(content) {
    const succerAlert = document.getElementsByClassName("alert")[0];
    succerAlert.classList.remove("alert-danger", "d-none");
    succerAlert.classList.add("alert-success");
    succerAlert.textContent = content;
}

function showFailAlert(content) {
    const alertError = document.getElementsByClassName("alert")[0];
    alertError.classList.remove("d-none", "alert-success");
    alertError.classList.add("alert-danger");
    alertError.innerHTML = content;
}

function hideAlert() {
    const alertError = document.getElementsByClassName("alert")[0];
    alertError.classList.add("d-none");
}

function compareDiffJSON(objInputFirst, objInputSecond, path = '') {
    let jsonFirstNull = ``;
    let jsonSecondNull = ``;
    let resultDiff = ``;

    for (let key in objInputFirst) {
      if (!objInputSecond.hasOwnProperty(key)) {
        jsonSecondNull += `  "${path}.${key}"
`;
        continue;
      }
      if (typeof objInputFirst[key] === 'object' && typeof objInputSecond[key] === 'object') {
        const valueDiff = compareDiffJSON(objInputFirst[key], objInputSecond[key], `${path}.${key}`);
        jsonFirstNull +=  valueDiff[0];
        jsonSecondNull += valueDiff[1];
        resultDiff += valueDiff[2];
        continue;
      }
      if (objInputFirst[key] !== objInputSecond[key]) {
        resultDiff += `  "${path}.${key}" is different: "${objInputFirst[key]}" vs "${objInputSecond[key]}"
`;
        continue;
      }
    }

    for (let key in objInputSecond) {
      if (!objInputFirst.hasOwnProperty(key)) {
        jsonFirstNull += `  "${path}.${key}"
`;
      }
    }

    return [jsonFirstNull, jsonSecondNull, resultDiff];
}

function handleJsonDifferent(objInputFirst, objInputSecond) {
    const resultCompare = compareDiffJSON(objInputFirst, objInputSecond,'');

    let jsonFirstNull = resultCompare[0];
    let jsonSecondNull = resultCompare[1];
    let resultDiff = resultCompare[2];

    if (jsonFirstNull === `` && jsonSecondNull == `` && resultDiff == ``) {
        const contentAlert = "The two Json were semantically identical!";
        showSuccessAlert(contentAlert);
        return;
    }

    const valueNull = `  Null
`;

    jsonFirstNull = (jsonFirstNull === ``) ? valueNull : jsonFirstNull;
    jsonSecondNull = (jsonSecondNull === ``) ? valueNull : jsonSecondNull;
    resultDiff = (resultDiff === ``) ? valueNull : resultDiff;

    let contentAlert = `
    Key is missing in the first JSON:

    ${jsonFirstNull}
   

    Key is missing in the second JSON:

    ${jsonSecondNull}
   

    Unequal value:

    ${resultDiff}`;
    showFailAlert(contentAlert);
}

function handleCompare() {
    const firstTextInput = document.getElementsByClassName("first-text-input")[0].value;
    const secondTextInput = document.getElementsByClassName("second-text-input")[0].value;

    if (firstTextInput == "") {
        const contentAlert = "You are not fill in the first data!"
        showFailAlert(contentAlert);
        return;
    }
    if (secondTextInput == "") {
        const contentAlert = "You are not fill in the second data!"
        showFailAlert(contentAlert);
        return;
    }

    let objInputFirst;
    let objInputSecond;
    try {
        objInputFirst = JSON.parse(firstTextInput);
        objInputSecond = JSON.parse(secondTextInput);
    } catch (error) {
        const contentAlert = "Change Parse fail!"
        showFailAlert(contentAlert);
        return;
    }

    handleJsonDifferent(objInputFirst, objInputSecond);
}

function handleDataFile(fileInput, positionAdd) {
    const file = fileInput.files[0];
    const reader = new FileReader();
    reader.onload = function(event) {
        const contentFile = event.target.result;
        if (contentFile == "") {
            const index = (positionAdd == "firstTextInput") ? "first" : "second";
            const contentAlert = "File " + index + " does not have data!";
            showFailAlert(contentAlert);
            return;
        }
        document.getElementsByClassName(positionAdd)[0].value = contentFile;
    }
    reader.readAsText(file);
    hideAlert();
}

function handleAddfile() {
    const firstUploadFile = document.getElementsByClassName('first-file-upload')[0];
    const secondUploadFile = document.getElementsByClassName('second-file-upload')[0];

    if (firstUploadFile.files.length != 0) {
        handleDataFile(firstUploadFile, "firstTextInput");
    }
    if (secondUploadFile.files.length != 0) {
        handleDataFile(secondUploadFile, "secondTextInput");
    }
}

document.addEventListener("DOMContentLoaded", function() {
    const btnCompare = document.getElementsByClassName("btn-compare")[0];
    const btnReset = document.getElementsByClassName("btn-reset")[0];
    const btnAddFile = document.getElementsByClassName("btn-add-file")[0];

    btnAddFile.addEventListener('click', function() {
        handleAddfile();
    });

    btnCompare.addEventListener('click', function() {
        handleCompare();
    });

    btnReset.addEventListener('click', function() {
        document.getElementsByClassName("first-text-input")[0].value = "";
        document.getElementsByClassName("second-text-input")[0].value = "";
        firstUploadFile.value = "";
        secondUploadFile.value = "";
        hideAlert();
    });
});


All together we have a JSON Diff tool as here 

 

Conclusion

In this article, we embarked on the journey of building a JSON Diff Tool using JavaScript, exploring the fundamental concepts, syntax, and data types of JSON along the way. The purpose and benefits of a JSON Diff Tool were outlined, showcasing its significance in scenarios such as version control systems, API development, and data synchronization. We delved into common use cases, emphasizing the tool's versatility in comparing JSON configuration files, validating API responses, and analyzing changes in large datasets.

The step-by-step guide to building the JSON Diff Tool covered essential aspects, from setting up the HTML structure to implementing JavaScript functions for comparison. The tool allows users to input two JSON objects, highlighting differences such as changes, additions, and deletions. The user-friendly interface, along with success and failure alerts, enhances the overall user experience.

By providing a practical solution for comparing JSON structures, this article aimed to empower developers and data analysts to troubleshoot and debug efficiently. The JSON Diff Tool presented here serves as a valuable resource for those working with JSON data in various domains.

 

FAQs

1. What is JSON?

JSON (JavaScript Object Notation) is a text-based data format derived from a subset of the JavaScript Programming Language. It is widely used for storing and exchanging information due to its simplicity and lightweight nature.

2. What are the key features of JSON syntax?

JSON syntax involves key-value pairs enclosed in curly braces ({}) and separated by commas. Keys are always strings, and values can be strings, numbers, booleans, arrays, objects, or null.

3. What is a JSON Diff Tool?

A JSON Diff Tool is a tool that compares two JSON objects and highlights their differences, aiding in the identification of changes, additions, and deletions between the structures. It is particularly useful in scenarios like version control, API development, and data synchronization.

4. What are some common use cases for a JSON Diff Tool?

Common use cases include comparing JSON configuration files for version tracking, validating API responses, identifying differences in large datasets during integration or migration processes, and analyzing changes in JSON-based data models or schema definitions.

5. How does the provided JSON Diff Tool work?

The tool involves a step-by-step process, starting with setting up the HTML structure and utilizing JavaScript functions for comparison. Users can input two JSON objects, and the tool highlights missing keys, unequal values, and structural differences, providing success or failure alerts based on the comparison results.

6. Can the JSON Diff Tool handle file inputs?

Yes, the tool supports file inputs, allowing users to compare JSON objects by uploading files. The tool reads the content of the files, compares the JSON structures, and presents the differences accordingly.

7. How can I reset the input and start a new comparison?

To reset the input and start a new comparison, users can click the "Reset" button provided in the interface. This clears the input fields and any uploaded files, ensuring a clean slate for the next comparison.


Related

Subscribe

Subscribe to our newsletter and never miss out lastest news.