What is the best way to compare two JSON structures in depth to determine whether they contain arrays or objects, without using JSON.stringify

I have been working on tracking changes in a mongoDB record that I send through a GET request and then update with a PUT request.

When the PUT request is received, I retrieve the existing document before updating it, and then compare it with the updated record. I exclude certain items like "updated_at" and a few other fields during the comparison process.

Here is my code snippet:

However, I am encountering an issue when calling the recursive comparison function. For the same array being checked, it always returns as modified, even if it isn't. Any suggestions or feedback?

You can find the complete JavaScript code on this jsfiddle: https://jsfiddle.net/vrw2ghja/8/

The objects _existingObj and _updatedObj are two different Objects, whereas, _cloneOf_existingObj is a clone of _existingObj

   
        
const compare = (obj1, obj2) => {
 
    // Implementation of the comparison logic
    
};
             

const check = (a, b) => {
       console.log("==========================");
       console.log(`Are objects ${a} and ${b} modified? ${compare(a, b)}`);
     
}

// Sample object instances
var _existingObj={ ... };
var _updatedObj={ ... };
var _cloneOf_existingObj={ ... };

check(_existingObj, _updatedObj);   
check(_existingObj,_cloneOf_existingObj);

Answer №1

To simplify the comparison process, you can create a function that breaks it down into steps.

  1. If the parameters are not objects, the function will return the result of using strict equality (===)
  2. If the parameters are objects but have different keys or a different number of keys, the function will return false
  3. If none of the above conditions are met, the values will be recursively passed back into the function to ensure they pass the aforementioned tests
function deepEqual(obj1, obj2){
    // Step 1
    if (obj1 === null || obj2 === null || typeof obj1 !== 'object' || typeof obj2 !== 'object') {
        return obj1 === obj2;
    }

    let [k1, k2] = [Object.keys(obj1), Object.keys(obj2)];

    // Step 2
    if (k1.length !== k2.length || !k1.every(k => k2.includes(k))) {
        return false;
    }

    // Step 3
    return k1.every(k => deepEqual(obj1[k], obj2[k]));
}

// Test some examples:

console.log("true ->", deepEqual([1, { name: "Mark", data: { age: 30 } }], [1, { name: "Mark", data: { age: 30 } }]));
// Extra parameter
console.log("false ->", deepEqual([1, { name: "Mark", data: { age: 30 } }], [1, { name: "Mark", data: { age: 30, city: "Paris" } }]));

// Different age
console.log("false ->", deepEqual([1, { name: "Mark", data: { age: 30 } }], [1, { name: "Mark", data: { age: 31 } }]));

// Literal 
console.log("true ->", deepEqual(30, 30));
console.log("true ->", deepEqual(null, null));

// Array 
console.log("true ->", deepEqual([30, [31, 32]], [30, [31, 32]])); // Equal arrays
console.log("false ->", deepEqual([30, [31, 32]], [30, [32, 31]])); // Not equal arrays

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can you simply hide Bootstrap alerts instead of deleting them when closing?

I am utilizing the power of Bootstrap 4 Alerts to showcase error messages, just like in their demo: <div class="alert alert-warning alert-dismissible fade show" role="alert"> <strong>Holy guacamole!</strong> You shou ...

What is the process of linking this JavaScript code to an outer stylesheet and integrating it with the HTML document?

After encrypting an email address using Hiveware Enkoder, the result can be found below. obfuscated code I typically include it directly inside the div as is. However, I would like to streamline my code by placing it in an external file. While I know ho ...

`meteor.js and npm both rely on the fs module for file

I'm feeling a bit lost, as I need to use the fs package with Meteor.js framework. Starting from meteor version 0.6 onwards, I know that I should use Npm.require in the following way: var fs = Npm.require('fs'); However, when I try this, a ...

The JSON response is missing the necessary key-value pairs, as only values are included

The PHP script below translates only the values, but I also require the key for each value: Desired output: [{"ID":"1","styleNo":"1","styleName":"Casual","placeholder":"Left Initial","type":"text","maxlength":"1","size":"small","position":"1"},{"ID":"2", ...

AngularJS causing issues with page redirection functionality

Incorporating angularjs routing into my web app has been a big task. I've set up the $locationProvider and included the base tag in the HTML head as <base href="/webapp/"> to get rid of the hash symbol in the URL. It's been smooth sailing w ...

Tips for connecting an input tag within a popover to a Vue Model

I've got an input nested inside a popover content as shown below: JSFiddle Link HTML code snippet: <div id="vue-app"> <div class="btn btn-primary" data-toggle="popover" data-placement="bottom" title="Hello World!" data-html="true" data ...

Creating an active tab using Material UI on a particular route

I've encountered an issue with Material UI tabs and need help figuring out how to resolve it. I have a navbar with three different tabs that link to separate URLs, but two of them are quite similar. Take a look at my code snippet below: <Tabs indic ...

Tips for integrating Google Analytics with React

In my react application, I have various pages: Main Service Contact Profile (private) etc.. To monitor user activity using Google Analytics, I came across the react-ga library which serves the purpose well. However, I find myself having to initialize G ...

Using Jquery to handle different status codes in an Ajax request

Currently, I am handling statusCode of 200 and 304 in a jQuery Ajax call. Additionally, I have defined an "Error" function to catch any errors that may occur. If a validation message is related, we specify the status code as 400 - Bad Request. In this sc ...

Is it possible to extract a user's password from the WordPress database for use in a React application

Is it feasible to create a React application integrated with Postgres within Wordpress that operates on MySql? I am interested in leveraging Wordpress's built-in features for theming, posts, and user management accounts. However, I am unsure if I can ...

Error 431 is encountered when submitting an Axios post request

Facing a 431 (Request Header Fields Too Large) error when trying to submit a form in my single-page project through an axios request. I've attempted setting maxContentLength and maxBodyLength to Infinity, as well as adding max-http-header-size in the ...

When submitting content to an asp.net core mvc application, it may lead to empty body and missing input parameters

I am delving into the world of asp.net core apps for the first time and while I have scoured through numerous StackOverflow posts, none seem to address my issue. I have an asp.net core mvc app running on service fabric and I am attempting to send a string ...

Calculating the number of rows in a dynamic jQuery table

I have a table structured like this: <div class="row"> <input type="button" id="btnAddGatePass" value="Add Gate Pass Requester" /> <div class="table-responsive"> <table id="gatePass" class="table table-striped table-ho ...

The mysterious case of the missing CSS file in Node.js

I recently set up a new Node.js Express Project. However, I am facing an issue with the index.ejs file showing the error: Undefined CSS file ('/stylesheets/style.css'). Here is the content of the index.ejs file: <!DOCTYPE html> <html& ...

Creating expandable card components with React and CSS using accordion functionality

I am currently working on creating a card that will expand its blue footer when the "view details" link is clicked to show lorem text. However, I am encountering an issue where the blue bottom of the card does not expand along with the lorem text. You can ...

Switching from a right arrow to a down arrow using jQuery for a collapsible accordion feature

I have developed a unique type of toggle feature similar to an accordion design. When I click on the right-arrow next to an item, such as Area A, it expands to reveal the list of items within Area A. The arrow also changes orientation to point downwards (L ...

The Redux dispatch function enters a loop when the success flag is set to true within the state

Currently, my Redux state is structured as follows: const initialState = { data: [], loading: false, success: false, error: null, }; I have implemented a CRUD API in the node backend. In my React application, I have two components: The first com ...

Utilize Express to deliver dynamically generated or stored images

My latest project is an innovative image delivery application that can serve images and dynamically resize/change their extension as needed. For the routing, I utilized Express and Sharp for processing the images. One challenge I encountered is high CPU ...

Is it possible to leverage the Next.js image component alongside canvas?

In my project, I am developing a scrollable image component inspired by the design of the Apple AirPods Pro website. To achieve this, I am utilizing images up to a size of 750 pixels for each iteration of the component. Currently, I am drawing these imag ...

Incorporating React into an existing jQuery single page application

My current dilemma involves transitioning from a jQuery-built single page app to React. The challenge I'm facing is that, when building sections at a time, issues arise during the process. One major obstacle is the necessity of passing in a parent "r ...