0

I am trying to build a webapp that gets data from server and shows it to user. Script gets data from server every 10 seconds and if data has changed it alerts user. This is the code I'm using now, but it alerts every 10 second whether the data has changed or not.

So how do I need to alter my scipt to make it compare the old JSON and the new JSON and see if they are different, and if they are show alert before updating data shown to user?

$('#ListPage').bind('pageinit', function(event) {
    getList1();
});
setInterval ( "getList1()", 10000 );
var old = "";

function getEmployeeList1() {
    $.getJSON(serviceURL + 'getemployees.php?' + formArray, function(data) {
        if(data != old){ // data from the server is not same as old
            $('#nollalista li').remove();
            keikka = data.key;
            $.each(keikka, function(index, lista) {
                $('#nollalista').append('<li><a href="employeedetails.html?id=' + lista.IND + '">' +
                        '<h4>' + lista.OSO + '</h4>' +
                        '<p>' + lista.AIKA + '</p>' +'</a></li>');
            });
            $('#nollalista').listview('refresh');

            if(old != "")
                alert("New data!");        
            old = data;
        }
    });
}  
user1256852
  • 53
  • 4
  • 13
  • 2
    how do you determine equality for two javascript objects : http://stackoverflow.com/questions/201183/how-do-you-determine-equality-for-two-javascript-objects – Fabrizio Calderan Apr 17 '12 at 09:52
  • 4
    **Never** pass a string to `setInterval()` or `setTimeout()`. Doing so is as bad as using `eval()` and it results in unreadable and possibly insecure code as soon as you use variables since you need to insert them into the string instead of passing the actual variable. The proper solution is `setInterval(function() { /* your code *) }, msecs);`. The same applies to `setTimeout()`. If you just want to call a single function without any arguments, you can also pass the function name directly: `setInterval(someFunction, msecs);` (note that there are **no** `()` behind the function name) – ThiefMaster Apr 17 '12 at 09:53

2 Answers2

7

A very easy (but kind of lame) solution is comparing the string representations:

if(JSON.stringify(a) != JSON.stringify(b)) { ... }
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 1
    nice, but it depends anyway if the order of properties matters or not – Fabrizio Calderan Apr 17 '12 at 09:56
  • Or even better don't stringify but just use the unparsed responseText from the ajax request. – Bergi Apr 17 '12 at 10:31
  • Run this in chrome dev tools, to see this solution fail. Although old, data have same properties/values. var old = {'a':1, 'b':2}, data = {'b':2, 'a':1}; if(JSON.stringify(old) != JSON.stringify(data)) 'failed comparison'; – Mr.Hunt Apr 17 '12 at 10:31
1

Your code alerts every 10 sec, because your comparison

    if(data != old){ // data from the server is not same as old

returns true everytime.

You can use this library to compare json in javascript https://github.com/prettycode/Object.identical.js and modify the comparison to

    if(!Object.identical(data,old)){ // data from the server is not same as old

usage:

var a = { x: "a", y: "b" },
b = { x: "a", y: "b" },
c = { y: "b", x: "a" },
d = { x: "Chris", y: "Prettycode.org", developerYears: [1994, 2011] },
e = { y: "Prettycode.org", developerYears: [1994, 2011], x: "Chris" };
f = { y: "Prettycode.org", developerYears: [2011, 1994], x: "Chris" };
console.log(Object.identical(a, b)); // true (same properties and same property values)
console.log(Object.identical(a, c)); // true (object property order does not matter, simple)
console.log(Object.identical(d, e)); // true (object property order does not matter, complex)
console.log(Object.identical(d, f)); // false (arrays are, by definition, ordered)
Mr.Hunt
  • 4,833
  • 2
  • 22
  • 28