0

In my app, I connect to a news service and pull back an array of articles; I do this every 20 minutes.

During that 20 minutes, I loop through the array of articles I have pulled, a new article from the array every 15 seconds.

My problem is that after 20 minutes, I get a new array from the news service and start looping through that array. Apparently, I am doing a double loop, the original array plus the new array.

Then, after another 20 minutes, I am looping through yet another array of news articles ... three in total now.

This continues throughout the day until it turns into an ugly mess.

I'm trying to figure out how to stop the original loop once I get a new array:

  • clearInterval(articleIntervalVar);
  • newsArticlesArray = null;

But nothing I have tried works, and I cannot figure it out.

newsFunction();
newsIntervalVar = setInterval(newsFunction, 1200000);

function newsFunction() {
    xmlHttpNewsObject = GetXmlHttpObject();

    if (xmlHttpNewsObject === null){
        alert ("Browser does not support HTTP Request");
        return;
    }

    var url = "";
    xmlHttpNewsObject.open("GET", url, true);
    xmlHttpNewsObject.onreadystatechange = getTheNews;
    xmlHttpNewsObject.send(null);
}

function getTheNews(){
    if (xmlHttpNewsObject.readyState == 4 && xmlHttpNewsObject.status == 200){
        var newsArticlesArray = JSON.parse(xmlHttpNewsObject.responseText).articles
        drawTheNews(newsArticlesArray);
        return;
    }
}

function drawTheNews(newsArticlesArray) {
    var news = document.getElementById('news');
    var numberOfArticles = newsArticlesArray.length;
    var i = 0;
    news.innerHTML = newsArticlesArray[i].title);
    var articleIntervalVar = setInterval(function () {
        i++;
        if (i === numberOfArticles) i = 0;
        news.innerHTML = newsArticlesArray[i].title);
    }, 15000);
}
Brian
  • 1,726
  • 2
  • 24
  • 62

2 Answers2

1

I'd use a slightly different logic, set the interval whenever you get a list of articles to display, and clear any existing interval right before that.

Also I have dusted off all the 20th century xmlHttp literature and replaced all that with fetch :)

const url = "...";
const newsElem = document.getElementById('news'); // cache your element instead of accessing it every time
let articles = [];
let articleInterval = null;

const newsFunction = async() => {
  try {
    const response = await fetch(url)
    articles = await response.json();
    clearInterval(articleInterval); // Clear the existing interval here
    articleInterval = setInterval(drawTheNews, 15000); // Set the new interval
  } catch (err) {
    console.log("Error getting the news : ", err)
  }
}

const drawTheNews = () => {

  const article = articles.pop();

  if (!article) {
    console.log("Depleted all news!")
    clearInterval(articleInterval)
    return;
  }

  newsElem.innerHTML = article.title
}

newsFunction();
setInterval(newsFunction, 1200000);
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
  • I tried this, but it seems that the `newsElem` is `null` when it comes time to write to its `innerHTML` – Brian Jun 08 '21 at 14:52
  • That's a totally different problem. It means your JS runs before your HTML has loaded. https://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element – Jeremy Thille Jun 08 '21 at 15:00
0

You just need to clear the timeout, move the ref to the global scope and clear it each time to remove the old scope

var articleIntervalVar;
newsFunction();
newsIntervalVar = setInterval(newsFunction, 1200000);

function newsFunction() {
    xmlHttpNewsObject = GetXmlHttpObject();

    if (xmlHttpNewsObject === null){
        alert ("Browser does not support HTTP Request");
        return;
    }

    var url = "";
    xmlHttpNewsObject.open("GET", url, true);
    xmlHttpNewsObject.onreadystatechange = getTheNews;
    xmlHttpNewsObject.send(null);
}

function getTheNews(){
    if (xmlHttpNewsObject.readyState == 4 && xmlHttpNewsObject.status == 200){
        var newsArticlesArray = JSON.parse(xmlHttpNewsObject.responseText).articles
        drawTheNews(newsArticlesArray);
        return;
    }
}

function drawTheNews(newsArticlesArray) {
    var news = document.getElementById('news');
    var numberOfArticles = newsArticlesArray.length;
    var i = 0;
    news.innerHTML = newsArticlesArray[i].title);
    clearInterval(articleIntervalVar);
    articleIntervalVar = setInterval(function () {
        i++;
        if (i === numberOfArticles) i = 0;
        news.innerHTML = newsArticlesArray[i].title);
    }, 15000);
}
Kyle
  • 1,463
  • 1
  • 12
  • 18