DEV Community

Cover image for Detecting Changes on JavaScript Object values using Sets
Vincent Kipyegon
Vincent Kipyegon

Posted on

Detecting Changes on JavaScript Object values using Sets

Most a times in Javascript you want to know if the contents of an object literal have changed i.e when a user updates/edits their information. Most developers will simply save the information to the server without necessarily finding out if user really changed a thing or two.

Javascript sets are a collection of ordered unique values and are helpful for eliminating duplicate values. Sets are essential when dealing with discrete data.

let nums=[4,4,4,4,2,2,2,3,3,3]
let distinctNums=new Set(nums)

// Set(3) {4,2,3}
// convert set to Array using spread operator
nums=[...distinctNums]    // [4, 2, 3]
Enter fullscreen mode Exit fullscreen mode

The example above is an array with duplicate values 2 and 3 ,when you initialize a new set with the array as an argument it returns set of 7 distinct values. That’s how it works.
You can read more about sets here on MDN

lets move on now; imagine, Ygritte is a beautiful single lady from Westeros North of the wall; here is a bio-data.

let user={name:"Ygritte",married:false,home:"North of the wall"}

Enter fullscreen mode Exit fullscreen mode

Then all over sudden, she meets the love of her life, Jon Snow, she gets married,relocates to Winterfell and lives happily thereafter,did they? You know nothing Jon Snow. So here is how her bio-data will look after marriage.

let user={name:"Ygritte Snow",married:true,home:"Winterfell"}

Enter fullscreen mode Exit fullscreen mode

But how will our Javascript detect that there are change of values on object literal?
Here is how we will do it

  1. Convert the object values of before and after marriage of Ygritte to an iterable in this case 2 arrays using Object.values()
  2. Merge the two arrays using spread operator
  3. Create a set of merged array as well as a set of initial before object
  4. Compare there sizes of before set and merged set.
let  before={name:"Ygritte",married:false,home:"North of the wall"}
let after={name:"Ygritte Snow",married:true,home:"Winterfell"}

let beforeArr=Object.values(before) //['Ygritte', false, 'North of the wall']
let afterArr=Object.values(after) //['Ygritte Snow', true, 'Winterfell']
let merged=[...beforeArr,...afterArr] //['Ygritte', false, 'North of the wall', 'Ygritte Snow', true, 'Winterfell']
// create sets
let mergedSet=new Set(merged)
let beforeSet=new Set(beforeArr)
if(mergedSet.size >beforeSet.size){
console.log('change detected')}
else{console.log('No change')}
Enter fullscreen mode Exit fullscreen mode

Whoa! I can explain what is happening here....

We merge our 2 arrays, create a merged set that will only return unique values and also create a set of before array. We then use the size property of Set to compare the sizes of before set (which are values of before object) and the merged set ( values of before and after objects).Typically we converted the values an object literal to an array then converted the array to a set.

If the size of mergedSet is bigger than beforeSet it means we have a new unique value on the after object, or simply the user info has been updated/modified.

Caveat

Most object literals have dynamic properties that are automatically generated by the database such as updated_at,created_at, the values of these properties will give a result that the object has been updated even though it has not.

To get around them, you can either delete the dynamic object property before creating arrays or taking them into account during comparison.

let  before={name:"Ygritte",married:false,home:"North of the wall",created_at :"11/09/2023"}
let after={name:"Ygritte Snow",married:true,home:"Winterfell",created_at:"27/11/2023"}

delete before.created_at;
delete after.created_at;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)