Retrieve the distinct elements between two objects within typescript/javascript angular

I'm attempting to retrieve the change object from two objects using TypeScript in Angular.

For example

this.productPreviousCommand = {
"id": "60f910d7d03dbd2ca3b3dfd5",
"active": true,
"title": "ss",
"description": "<p>ss</p>",
"category": {
    "id": "60cec05df64bde4ab9cf7460"
},
"subCategory": {
    "id": "60cec18c56d3d958c4791117"
},
"vendor": {
    "id": "60ced45b56d3d958c479111c"
},
"type": "load_product_success"

}

model = {
"active": true,
"title": "ss",
"description": "<p>ss sss</p>",
"category": "60cec05df64bde4ab9cf7460",
"subCategory": "60cec18c56d3d958c4791117",
"vendor": "60ced45b56d3d958c479111c",
"tags": []

}

The difference between the two objects is

description: "<p>hello hello 1</p>"
. Therefore, I aim to return
{description: "<p>hello hello 1</p>"}

To achieve this, I incorporated lodash library from https://github.com/lodash/lodash

import { transform, isEqual, isObject, isArray} from 'lodash';

function difference(origObj, newObj) {
  function changes(newObj, origObj) {
    let arrayIndexCounter = 0
    return transform(newObj, function (result, value, key) {
      if (!isEqual(value, origObj[key])) {
        let resultKey = isArray(origObj) ? arrayIndexCounter++ : key
        result[resultKey] = (isObject(value) && isObject(origObj[key])) ? changes(value, origObj[key]) : value
      }
    })
  }
  return changes(newObj, origObj)
}

However, I encountered an issue with this library as it returns the entire object when using the code const

differenc = difference(this.productPreviousCommand, model);

The output generated by the above code snippet is

{
    active: true
    description: "<p>hello hello 1</p>"
    id: "60f8f29dd03dbd2ca3b3dfd1"
    title: "hello"
    }

Answer №1

Give this function a try

compareObjects(objA: any, objB: any): any {
        let differentProperties: any = {};
        for (const property in objA) {
            if (Object.prototype.hasOwnProperty.call(objA, property)) {
                if(objA[property] !== objB[property]) {
                    differentProperties[property] = objA[property];
                }
                
            }
        }

        return differentProperties;
    }

Answer №2

To compare two objects, loop through each key in the first object and check for differences with the second object.

function findObjectDifferences(obj1, obj2) {
  return Object.entries(obj1).reduce((differences, [key, value]) => {
    // Check if the property exists in obj2.
    if (obj2.hasOwnProperty(key)) {
      const val = obj2[key];

      // Compare values of properties from both objects.
      if (val !== value) {
        return {
          ...differences,
          [key]: val,
        };
      }
    }

    // Return the updated differences or previous diff object.
    return differences;
  }, {});
}

const firstObj = {
  active: true,
  description: '<p>hello</p>',
  id: '60f8f29dd03dbd2ca3b3dfd1',
  title: 'hello',
};
const secondObj = {
  active: true,
  description: '<p>hello hello 1</p>',
  id: '60f8f29dd03dbd2ca3b3dfd1',
  title: 'hello',
};
const thirdObj = {
  active: true,
  description: '<p>hello hello 2</p>',
  id: '60f8f29dd03dbd2ca3b3dfd1',
  title: 'world',
};

console.log(findObjectDifferences(firstObj, secondObj));
console.log(findObjectDifferences(secondObj, thirdObj));

Answer №3

function compareObjects(obj1, obj2) {
  const keysObj1 = Object.keys(obj1),
    keysObj2 = Object.keys(obj2);

  // check if objects have different lengths
  if (keysObj1?.length !== keysObj2?.length) {
    return;
  }

  // check for differences in keys between objects
  if (Object.keys(obj1).filter((key) => !Object.keys(obj2).includes(key))?.length) {
    return;
  }

  return Object.entries(obj1).reduce(
    (acc, [key, value]) => (obj2[key] !== value ? { ...acc, ...{ [key]: obj2[key] } } : acc),
    []
  );
}

const objectA = {
  active: true,
  description: '<p>hello</p>',
  id: '60f8f29dd03dbd2ca3b3dfd1',
  title: 'hello',
};

const objectB = {
  active: true,
  description: '<p>hello hello 1</p>',
  id: '60f8f29dd03dbd2ca3b3dfd1',
  title: 'hello',
};


console.log(compareObjects(objectA, objectB));

Feel free to test out this code snippet.

function compareObjects(obj1, obj2) {
  const keysObj1 = Object.keys(obj1),
    keysObj2 = Object.keys(obj2);

  // check if objects have different lengths
  if (keysObj1?.length !== keysObj2?.length) {
    return;
  }

  // check for differences in keys between objects
  if (Object.keys(obj1).filter((key) => !Object.keys(obj2).includes(key))?.length) {
    return;
  }

  return Object.entries(obj1).reduce(
    (acc, [key, value]) => (obj2[key] !== value ? { ...acc, ...{ [key]: obj2[key] } } : acc),
    []
  );
}

Answer №4

If you need to compare two objects in TypeScript and find their differences, you can create a function that traverses the objects recursively and checks for variations in their properties. Here's an example of how you can implement this:

function findObjectDifferences(obj1: any, obj2: any): any {
  if (typeof obj1 !== 'object' || typeof obj2 !== 'object') {
    return obj1 !== obj2 ? [obj1, obj2] : undefined;
  }

  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  const allKeys = new Set([...keys1, ...keys2]);

  const differences: any = {};

  for (const key of allKeys) {
    const value1 = obj1[key];
    const value2 = obj2[key];

    if (typeof value1 === 'object' && typeof value2 === 'object') {
      const nestedResults = findObjectDifferences(value1, value2);
      if (nestedResults) {
        differences[key] = nestedResults;
      }
    } else if (value1 !== value2) {
      differences[key] = [value1, value2];
    }
  }

  return Object.keys(differences).length === 0 ? undefined : differences;
}

const object1 = {
  name: 'John',
  age: 30,
  address: {
    city: 'New York',
    zip: '10001',
  },
};

const object2 = {
  name: 'Jane',
  age: 28,
  address: {
    city: 'San Francisco',
    zip: '94101',
  },
};

const discrepancies = findObjectDifferences(object1, object2);
console.log(discrepancies);

Output

{
  "name": [
    "John",
    "Jane"
  ],
  "age": [
    30,
    28
  ],
  "address": {
    "city": [
      "New York",
      "San Francisco"
    ],
    "zip": [
      "10001",
      "94101"
    ]
  }
} 

The findObjectDifferences function compares two objects, identifies their discrepancies, and returns an object detailing the distinctions between them. If no differences exist, it returns undefined. This sample demonstrates a comparison between two objects - object1 and object2, even accounting for nested objects.

Keep in mind that this is a basic illustration, and you may need to enhance it based on your unique requirements, accommodating diverse data types and special cases.

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 to Retrieve Data from a JSON Object with JavaScript

I'm working with a JSON object that looks like this: ({ "codes": [ { "code": { "redeemed": "true", "retailer": "R1", "code": "ab11845b55b3ef1c3f137a35dbdfb270" } }, { "code": { ...

Implement lazy loading of content on scroll in Grails framework

Currently, I am uploading images and displaying them in a gsp view. My goal now is to implement a functionality where the images load as I scroll down on the page. A friend suggested using jQuery to make an ajax call for this. Can someone please provide g ...

Encountering the error "Object is not a function" while utilizing supertest/superagent within a forEach iteration

My current challenge involves using supertest to test multiple URLs while following the same set of rules. var urls = [ "https://www.example.com", "https://www.example2.com" ]; urls.forEach(function (url) { console.log('begin'); ...

Looking to switch up the hide/show toggle animation?

Currently, I have a functioning element with the following code. It involves an object named #obj1 that remains hidden upon page load but becomes visible when #obj2 is clicked. #obj1{ position:fixed; width:100px; bottom:180px; right:10 ...

Connecting table checkboxes to buttons in Angular 4.x: A step-by-step guide

Exploring Angular 4.x for the first time and faced with a challenge. I have created an HTML table where each row contains a checkbox and buttons. My goal is to link the checkboxes with the buttons in such a way that when a checkbox is checked, the correspo ...

AngularJS Expandable Table - Unlocking Limitless Possibilities

Take a look at the code snippet below: <tbody> <tr ng-repeat-start="ticket in tickets"> <td> <button ng-if="ticket.expanded" ng-click="ticket.expanded = false">-</button> <button ng-if="!t ...

Centering Card Content in Angular Using Material Design

I am attempting to align the text in the center of this angular material card. Presently, it is horizontally centered, but I aim to achieve vertical alignment as well. HTML: <mat-card class="card-initials"> <div> BD </div> ...

Libraries that automatically suggest options for integrating objects described by JSON schema

We are currently developing a platform with an email templating feature. Users can insert objects and variables into their emails using json-schema. Although we are not the first ones to work on this, our research has not turned up many libraries that cou ...

[Vue alert]: The event "lazyLoadError" was triggered with an undefined handler

Currently, I am utilizing the combination of vue js and laravel. To enhance my project, I decided to incorporate a Vue component for Slick-carousel, but encountered the following error: [Vue warn]: Invalid handler for event "lazyLoadError": got unde ...

Show an Array of Nested JSON API information on an HTML page using jQuery/JavaScript

Recently, I've delved into the world of jQuery, JavaScript, and AJAX while experimenting with an API that I designed. The backend result I received looks like this: [ { "id": 1, "choice_text": "They work on List View generally", ...

Challenges with the Express server console

I have configured an Express Server and everything appears to be functioning correctly. The content I send is rendered in the browser, and my console.log test statements are being displayed in the terminal. However, when I inspect the browser page, nothi ...

Encountering difficulties with image processing on a web page

Recently, I've been experimenting with uploading an image and converting it to a grayscale version on my webpage. Oddly enough, the javascript code works perfectly when tested locally but fails to generate the grayscale image once integrated onto the ...

What is the best method for distributing this array object?

I am faced with the task of spreading the following object: const info = [{ name: 'John', address: 'america', gender: 'Male', job: 'SE' }]; I want to spread this array object and achieve the following format: form:{ ...

Leveraging Angular component in codebases of AngularJS and Angular versions

I am currently trying to implement the TableComponent within the AppInventoryModule // app-inventory.component.html ... <div class="table-container"> <mat-table [model]="tableModel" (sortChange)="onSortChange($ ...

Testing a TypeScript function with Jest by mocking a function that is invoked from a separate file

In my code, there is a function called processCosts located in the file prepareStatement.ts. This function makes a call to another function named calculatePrice, which is imported from coreLogic.ts. Within my test file reports.integration.ts, I have impor ...

Creating a single form field with two inputs and applying custom styling in Angular Material can be achieved by following these steps

In my Angular Material project, I am creating a sample application with a form that includes a field with an input and dropdown. Currently, I have utilized flex styles and attributes as shown below: <div class="row"> <mat-label>De ...

What is the method for updating a property in an object of a Typescript class?

I am trying to work with a Fruit class: export class Fruit { constructor(public id: number, public name: string) {} public changeName(_name: string): void { console.log('changing name') this.name = _name } } My imple ...

I am struggling to understand how to work with constrained generic functions

function calculateMinimumLength<T extends {length : number}>(arg1: T, arg2: T) : T { if (arg1.length >= arg2.length) { return arg2; } else { return arg1; } } let str = "Hello world"; const result0 = calculateMinimumLe ...

Generating a task list in React and facing an issue related to an array

I am facing an issue with conditionally rendering a task group based on whether they are marked as completed or pending. function TaskList() { const { tasks } = useContext(TaskContext); return tasks.length === 0 ? ( <h2>No tasks added yet< ...

Ways to retrieve the currently selected id from the router within the next 14 steps

I'm currently trying to extract the ID that is selected (#about, #home, #blog) or the full path (http://localhost:3000/#about, http://localhost:3000/#home) from the router. I am working with Next.js version 14.0.3 This is my approach: My current URL ...