0

I am trying to better understand the use of deferred objects in jQuery.

The getData method below fetches some data asynchronously. When done, it should be displayed to some predefined (log) section by addToChart. This should happen periodically, hence my using setInterval inside getData's done handler.

function getData() {
    return $.ajax({
        url: 'https://demo-live-data.highcharts.com/time-data.csv',
        type: 'GET'
    });
}
getData().done(addToChart, function() {
    setInterval(getData, 1000);
});

function addToChart(data) {
    document.getElementById('log').innerText += data;
}

$(document).ready(function() {
    getData();
});

In above code, getData seems to get called only once. How do I let it be called periodically?

Also, is there any way to actually debug this code, rather than run it and scratch my head why it doesn't behave as expected? (I'm new to JavaSCript, in case you wonder). I stepped through the code using the Firefox debugger but that didn't help.

bwcoder
  • 47
  • 7

3 Answers3

0

You would need to do a while loop :

while (condition) {
    code block to be executed
}

or the do/while loop :

do {
    code block to be executed
}
while (condition);
Bret Hawker
  • 99
  • 1
  • 11
0

setTimeout is used to delay a function https://www.w3schools.com/jsref/met_win_settimeout.asp

What you want to use is setInterval https://www.w3schools.com/jsref/met_win_setinterval.asp

So looking at what you're trying to do, i would do it like this:

$(document).ready(function() {
    function getData() {
        $.ajax({
            url: 'https://demo-live-data.highcharts.com/time-data.csv',
            type: 'GET'
        }).done(addToChart);
    }

    function addToChart(data) {
        document.getElementById('log').innerText += data;
    }

    setInterval(getData, 1000);
});
  • 1
    done syntax is incorrect. You are invoking `addToChart` immediately – charlietfl May 21 '18 at 18:06
  • @charlietfl just fixed that, thanks for catching that – Long M K Nguyễn May 21 '18 at 18:07
  • This works, but I wonder why things break if I try to decouple the data handler from the ajax request, i.e. I move the `done` handler out of the `getData` function: `getData.done(addToChart);` – bwcoder May 21 '18 at 18:51
  • 1
    @badweathercoder i haven't tested but u can decouple it further if you want to, moving `done` handler outside, so getData needs to return the ajax object `function getData() {return $.ajax(....);}`, then in the setInterval like this: `setInterval(function() { getData().done(addToChart); }, 1000);` – Long M K Nguyễn May 21 '18 at 19:01
  • Thanks, that fixed it. Any idea why this doesn't work: `setInterval(getData, 1000); getData.done(addToChart);`, while your suggestion `setInterval(function() { getData().done(addToChart); }, 1000);` works? – bwcoder May 21 '18 at 19:13
  • 1
    Because when you call `setInterval(getData, 1000)` it will only execute getData and doesn't acknowledge the callback for done, which you're calling on the next line and this is not connected to the setInterval – Long M K Nguyễn May 21 '18 at 19:26
0

Move the done inside the function so it will get called every time the function does and request succeeds

function getData() {
  return $.ajax({
      url: 'https://demo-live-data.highcharts.com/time-data.csv',
      type: 'GET'
    })
    .then(addToChart)
    .always(function() {
      setTimeout(getData, 1000);
    });
}

Alternate approach is wrap what you are currently doing in a new function

function getData() {
  return $.ajax({
    url: 'https://demo-live-data.highcharts.com/time-data.csv',
    type: 'GET'
  });
}

function loadChart() {
  getData()
    .then(addToChart)
    .always(function() {
      setTimeout(loadChart, 1000);
    });

}

loadChart()
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • This seems similar to doing it the "old" jQuery way, where you define a `success` as success handler. I'd like to decouple the callback handling from the AJAX request as much as possible. – bwcoder May 21 '18 at 18:09
  • Then use a separate function that calls `getData` and put the timeout in that function and call the new function instead each time – charlietfl May 21 '18 at 18:11
  • See alternative approach – charlietfl May 21 '18 at 18:15