1

I am writing an app running inside a browser. Every minute I load a json file from my server with current data and need compare these data with data from the previously loaded json file. If there is any change, I will show new data dynamically inside the app.

I have used a function with a delay for it. Example at the JSfiddle. However, I am not able to get local variables from the function with the delay into next function, in which I would be able to compare the data.

I have tried create global variables, tried work with scope variables, and even save values in storage. Nothing has been working for me. Output from the JSON file are objects.

Any help, please? JSfiddle: https://jsfiddle.net/vladoss/r02aLv60/2/

dataUpdates();
var ch1;
     
function dataUpdates() {
    ch = (function() {
      ch = null;
      $.ajax({
          'async': false,
          'global': false,
          'url': "json.json", //non-exisitng json.
          'dataType': "json",
          'success': function (data) {
              ch = data;
          }
        });
        return ch; //current data
    })();
          
    setTimeout(oldValues, 3000);
    function oldValues() {
     ch1 = ch[0]; //old data
    }

    if (ch1 !== ch[0]) { //Here I need be able to read variable ch1.
       console.log(ch1); //ch1 is undefined
       //...
 }
}
setInterval(dataUpdates, 5000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
Vlados
  • 13
  • 4

3 Answers3

1

You can compare checksums of two json files. For this you can use library . Code structure can be simplified to this.

var curCh = null;

function dataUpdates() {
    $.ajax({
      'async': false,
      'global': false,
      'url': "json.json", //non-exisitng json.
      'dataType': "json",
      'success': function (data) {
          var ch = checksum(data);

          // Comparing checksums
          if(curCh != ch) {
              curCh = ch; 

              console.log('new json! do updates here!');
          }
      }
    });  
}   

setInterval(dataUpdates, 5000);
Mike Kor
  • 876
  • 5
  • 14
  • is there possible directly check individual objects inside the json file or only whole json? In my case I have tried compare two individual objects pulled out of one json file. JSON contains 8 objects. (before and after update). – Vlados Jan 12 '16 at 16:31
  • sure. you can loop through all of the json keys for(var k in obj) { console.log(obj[k]); } And compare desired keys if not all of them. – Mike Kor Jan 12 '16 at 16:35
  • Let's say json is obj = { "name": "test", "phone": "123" }. To access it use obj.name or obj.phone. To compare just use if(curObj.name == obj.name) { console.log("true"); } – Mike Kor Jan 12 '16 at 16:39
0

JSFiddle is down. :(

You seem to use both ch and ch1 before they get assigned. In case of ch1 it's easy to see:

if (ch1 !== ch[0])

Will get executed almost 3 seconds before you assign a value for the 1st time in oldValues.

And you also use ch[0] in 2 places without checking whether ch or ch[0] are set!

You might try this:

setTimeout(oldValues, 3000);
oldValues();
function oldValues() {...

So ch1 will have a value immediately after the sync AJAX finished, and before you try to use it for the 1st time in the if

And I would also get rid of the ch = function and ch = null. Why do you have them?

Besides ch1 !== Ch[0] will be true after each AJAX response, even if the JSON hasn't changed! See:

a = {} ; b = {} ; console.log(a == b)

This is because you get a different object with a different reference, and even though their values are the same == doesn't compare them. Maybe this can help: Object comparison in JavaScript

And an even better solution would be to use Etag with http://api.jquery.com/jquery.ajax/. Search for "ifModified" and "etag" in the link.

Community
  • 1
  • 1
Gavriel
  • 18,880
  • 12
  • 68
  • 105
  • Yes, I need have ch1 !== ch[0] during initial load, because this will also load some features. Then, I want always save ch[number] (json data) into variable ch+someNumber, which is executed few secs after new load of JSON. In the meanwhile, i want check wheteher there was any change. – Vlados Jan 12 '16 at 16:07
  • If I use oldValues();, then ch[0] will be equivalent to ch1 during initial load and some parts of my app will not displayed. – Vlados Jan 12 '16 at 16:14
  • then: if (ch1 && ch && ch[0] && ch1 !== ch[0]) – Gavriel Jan 12 '16 at 16:14
  • See also my update why ch1 !== ch[0] will not do what you intend IMHO – Gavriel Jan 12 '16 at 16:19
0

I solved it by this way. It works fine for me.

dataUpdates();

function dataUpdates() {
 ch = (function() {
     ch = null;
     $.ajax({
         'async': false,
         'global': false,
      'url': "json.json",
      'dataType': "json",
         'success': function (data) {
             ch = data;
         }
     });
     return ch;
 })();

    setTimeout(oldValues, 20000); //run oldValues function after 20s
};

function oldValues() { //save previous ch into variable
     ch1 = ch;
    setTimeout(checkData, 20000);   //wait 20s and compare previous ch(=ch1) with current ch
};

function checkData(){
 console.log(ch[0].Title);
 console.log(ch1[0].Title);
}

setInterval(dataUpdates, 30000); //run dataUpdates function every 30s
Vlados
  • 13
  • 4