Detecting Changes on JavaScript Object values using Sets
Tags: javascript, beginners, webdev, react
Published: 2023-11-29 10:09:16

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.

```javascript
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]
```

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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
)

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

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

```

_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.

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

```

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. 

```javascript
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')}
```

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.



```javascript
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;
```