0

I have an API data source (JSON) that yields 12 new results every 60 seconds. The client wants a little pop-up to show up in the bottom corner of their website saying "UserX just earned $y from their app." They want to use real data from the API, and they want the results to be shown on a semi-random basis, so it looks "natural".

So - basically every 60 seconds, I want to call the API to get a new set of 12 records... and in the 60 seconds that follow, cycle through the 12 records that I got in random intervals (between 3 - 7 seconds).

Here is my code thus far:

  $(document).ready(function(){
      function gatherData() {
          $.ajax({
              dataType: "json",
              url: "https://www.somesite.com/api-endpoint",
              success: function(data) {
                  loopThroughData(data, 0);
              }
          });
       }

       function loopThroughData(data, i) {

           var randomTime = Math.floor(Math.random() * (Math.floor(7000) - Math.ceil(3000)) + Math.ceil(3000));
  
           setTimeout(function(){
               var rewardString = name + " just earned "+data.currency+" " + data.currency_name + "s and $"+data.dollar_amount+" for the "+data.platform+". <span>"+data.location+"  - A few seconds ago</span>";
    
               $("#reward-body").empty().append(rewardString);
               $("#reward-notification").fadeIn('slow').delay(3000).fadeOut('slow');
    
               i++;
    
               if (i < 12) {
                   loopThroughData(data, i);
               }
           }, randomTime);
       }

       var outerLoop = setInterval(gatherData(), 60000);
  });

With this code, it does indeed call the data source, and cycles through the results in random intervals. However, once it gets through the initial 12 results, it does not call the data source again. So, it appears as though my setInterval isn't working. I attempted this both with the defining variable (var = outerLoop), as well as without it, but that doesn't seem to make a difference. I also adjusted the 60000 ms time to 6000 just to see if it calls the gatherData() function more than once. It does not.

You can see this all in action here: https://codepen.io/johnhubler/pen/YzqGrGz

Does using setTimeout negate setInterval, or am I just missing something silly? Any help would be appreciated!

John Hubler
  • 877
  • 1
  • 11
  • 27
  • `setInterval(gatherData(), 60000)` should be `setInterval(gatherData, 60000)` (without parenthesis after `gatherData`). – Ivar Aug 20 '20 at 14:15
  • 1
    Just FWIW (it's not the problem, the problem is calling `gatherData` rather than passing it into `setInterval`, as keen-eyed @Ivar noted): This line: `var randomTime = Math.floor(Math.random() * (Math.floor(7000) - Math.ceil(3000)) + Math.ceil(3000));` is this line with three unnecessary function calls and an unnecessary subtraction: :-) `var randomTime = Math.floor(Math.random() * 4000) + 3000;` Both do the exact same thing: generate a random number between 4000 (inclusive) and 7000 (exclusive). – T.J. Crowder Aug 20 '20 at 14:17
  • 2
    `(Math.floor(7000) - Math.ceil(3000)) + Math.ceil(3000)` <-- why are you using floor and ceil on integers? – epascarello Aug 20 '20 at 14:17
  • Okay @Ivar - I made a few updates based on the suggestions here. (Thank you btw!). I changed my setInterval call to be simply: setInterval(gatherData, 60000); as suggested. However... now, it seems as though the script waits 60 seconds before fetching the data for the first time. Do I need to initiate a function call prior to the setInterval to kick things off? (If you want to see the changes, the URL is the same) – John Hubler Aug 20 '20 at 14:59
  • @JohnHubler Yes. See [Execute the setInterval function without delay the first time](https://stackoverflow.com/questions/6685396/execute-the-setinterval-function-without-delay-the-first-time). – Ivar Aug 20 '20 at 15:04

0 Answers0