0

I'm trying to compare two objects. I use socket.io to send the nodes object to the client.

My server.js goes:

var nodes = {'101':{ID:'101',x:100,y:200},
             '102':{ID:'102',x:200,y:200}};
socket.emit('message', nodes);

In my client, I'd like to create a copy of the object nodes only for the first time it receives. Save it to the variable oldNodes and the next time the socket receives the nodes object, do a comparison with oldNodes and output which property has been changed.

E.g., if it receives var nodes = {'101':{ID:'101',x:100,y:200},'102':{ID:'102',x:200,y:300}};, it should print(console.log) that nodes[102].y is changed.

client.html :

socket.on('message', function(nodes){
    if (oldNodes == undefined){
        var oldNodes = nodes;
   }
   else{
       //compare oldNodes & nodes
       //print result
  }
});

For copying, var oldNodes = nodes; is not what I want since javascript passes objects as a reference. So, even if oldNodes & nodes have the same content, (oldNodes == nodes) will produce a false. How do I copy the object and COMPARE its properties efficiently?

J.Jay
  • 249
  • 1
  • 4
  • 18

4 Answers4

2

From your code it seems like the problem is not passbyref related. If you declare oldNodes outside of your function and then assign it with var inside the if statement, oldNodes will not be defined in the else block. This might be what you are looking for?

if (oldNodes == undefined){
    oldNodes = nodes;
}
noveyak
  • 3,240
  • 1
  • 19
  • 19
  • i can't write `oldNodes = nodes;` It'll just copy the reference to the "nodes" object. So, when I change something to `oldNodes`, the `nodes` object will be effected, too. – J.Jay Jul 02 '15 at 06:23
  • 1
    Have you tested this? The nodes that are getting pushed to you in the socketio code is from ws and isn't referring to anything else. – noveyak Jul 02 '15 at 06:37
  • `if (oldNodes == undefined){ oldNodes = nodes; } oldNodes[101].x = 500; console.log(nodes[101].x);` console prints 500 in the first time. – J.Jay Jul 02 '15 at 08:08
2

You can try:

if (typeof oldNodes === 'undefined') {
    // use deep copy of Jquery
    var oldNodes = jQuery.extend(true, {}, nodes); 
} else {
   //compare oldNodes vs. nodes
   //print result
}
long.luc
  • 1,191
  • 1
  • 10
  • 30
1

1) Simple clone:

var oldNodes = JSON.parse(JSON.stringify(nodes));

2) Use this lib to compare: https://github.com/benjamine/jsondiffpatch

stdob--
  • 28,222
  • 5
  • 58
  • 73
1

As you said

For copying, var oldNodes = nodes; is not what I want since javascript passes objects as a reference.

This is not the case here:

Your code is right, just go with it, you won't get any reference issue as every time you receives a data from socket it is a new Object.

This is the final code you need, give it a try

var oldNodes = undefined
socket.on('message', function(nodes){
    createFirstTime_And_CompareElse(nodes)
});


var createFirstTime_And_CompareElse = function(newObj) {
    if (oldNodes == undefined){
        oldNodes = newObj;
    }
    else{
        //compare oldNodes & newObj
        //print result
        for(each in oldNodes) {
            for(subEach in oldNodes[each])
            if(oldNodes[each][subEach] != newObj[each][subEach]) {
                console.log("newObj[" + each + "]" + "[" + subEach + "] is changed")
            }
       }
    }
}
Harpreet Singh
  • 2,651
  • 21
  • 31
  • let's assume that I make some changes to oldNodes. Will the newObj be changed right after my modification to oldNodes? Cuz there are other parts of the program(other objects that change according to the change in newObj) that depends on that newObj, – J.Jay Jul 02 '15 at 07:50