'stopping and restarting an interval (or timeout?)
I have a script that checks the hour and creates elements in a div if certain conditions are met (if the hour is betwwen 6 and 8 it creates a morning list, if the hour is between 19 and 20 it creates an evening list. The problem is, I've set both a timeout and an interval on the script (different tests, not together at the same time) to get it to constantly check the hour, and it then continues to append to the ul. I want the function to get called continually to stay up to date, but I want it to stop running prior to creating the new elements if the hour arguments are met. I'm having difficulty with this... here's my code.
My coding is getting ahead of my learning... thank you again for any assistance offered, reading other articles here has been a big help in figuring out how to make pieces of this application work. Every once in a while I run into an issue I can't seem to read my way out of, though.
morningMedsList = ['med1', 'med2', 'med3', 'med4', 'med5'];
eveningMedsList = ['med1', 'med2', 'med3', 'med4', 'med5'];
const hour = new Date().getHours();
function listMeds() {
if (hour >= 6 && hour <= 8) {
clearInterval(listMeds);
} else if (hour >= 19 && hour <= 20) {
clearInterval(listMeds);
} else {}
if (hour >= 6 && hour <= 8) {
let morningMeds = document.getElementById('morning-meds-list');
mornMed = document.createElement('li');
morningMedsList.forEach(function (med, index) {
clone = mornMed.cloneNode();
clone.textContent = (index +1) + '. ' + med;
morningMeds.appendChild(clone);
});
} else if (hour >= 19 && hour <= 23) {
let eveningMeds = document.getElementById('evening-meds-list');
eveMed = document.createElement('li');
eveningMedsList.forEach(function (med, index) {
clone = eveMed.cloneNode();
clone.textContent = (index +1) + ': ' + med;
eveningMeds.appendChild(clone);
});
}
console.log('test');
}
setInterval(listMeds, 5000);
Solution 1:[1]
You need to assign the interval to a global variable, and use this in the call to clearInterval().
You also should get the hour inside the listMeds function. Otherwise you'll always be checking the time when the page loaded, not the current time that the interval function is running.
morningMedsList = ['med1', 'med2', 'med3', 'med4', 'med5'];
eveningMedsList = ['med1', 'med2', 'med3', 'med4', 'med5'];
let medsInterval = setInterval(listMeds, 5000);
function listMeds() {
const hour = new Date().getHours();
console.log(hour);
if (hour >= 6 && hour <= 8) {
clearInterval(medsInterval);
} else if (hour >= 19 && hour <= 20) {
clearInterval(medsInterval);
} else {}
if (hour >= 6 && hour <= 8) {
let morningMeds = document.getElementById('morning-meds-list');
mornMed = document.createElement('li');
morningMedsList.forEach(function(med, index) {
clone = mornMed.cloneNode();
clone.textContent = (index + 1) + '. ' + med;
morningMeds.appendChild(clone);
});
} else if (hour >= 19 && hour <= 23) {
let eveningMeds = document.getElementById('evening-meds-list');
eveMed = document.createElement('li');
eveningMedsList.forEach(function(med, index) {
clone = eveMed.cloneNode();
clone.textContent = (index + 1) + ': ' + med;
eveningMeds.appendChild(clone);
});
}
console.log('test');
}
Morning Meds
<ul id="morning-meds-list"></ul>
Evening Meds
<ul id="evening-meds-list"></ul>
Solution 2:[2]
I think the point is that you don't want to clear that interval otherwise how are you going to fire it up again? I think you just need a flag to check wheteer the list has already been printed, and do not print again in that case. Clear the list when you are out of the time range, and change the flag again, and so on:
const morningMedsList = [
'morning_med1',
'morning_med2',
'morning_med3',
'morning_med4',
'morning_med5',
];
const eveningMedsList = [
'evening_med1',
'evening_med2',
'evening_med3',
'evening_med4',
'evening_med5',
];
const medsHours = [6, 7, 8, 19, 20, 21, 22, 23];
const morningContainer = document.getElementById('morning-meds-list');
const eveningContainer = document.getElementById('evening-meds-list');
let wasWithinRange = false;
let hour = new Date().getHours();
function listMeds() {
hour = new Date().getHours();
console.log('CHECKING TIME, HOUR:', hour);
if (!medsHours.includes(hour) && wasWithinRange) {
console.log('RESETTING FLAG');
wipeNodes([morningContainer, eveningContainer]);
wasWithinRange = false;
}
if (hour >= 6 && hour <= 8 && !wasWithinRange) {
console.log('CREATING MORNING LIST');
createElems(morningContainer, morningMedsList);
wasWithinRange = true;
}
if (hour >= 19 && hour <= 23 && !wasWithinRange) {
console.log('CREATING EVENING LIST');
createElems(eveningContainer, eveningMedsList);
wasWithinRange = true;
}
}
setInterval(listMeds, 5000);
function createElems(elem, list) {
const item = document.createElement('li');
list.forEach(function(med, index) {
const clone = item.cloneNode();
clone.textContent = index + 1 + '. ' + med;
elem.appendChild(clone);
});
}
function wipeNodes(elems) {
elems.forEach((elem) => (elem.innerHTML = ''));
}
/*
TESTING
*/
const btn = document.querySelector('button');
btn.onclick = () => {
hour = Number(prompt('SET HOUR:'));
};
<div id="morning-meds-list"></div>
<div id="evening-meds-list"></div>
<button>SET HOUR MANUALLY FOR TESTING</button>
I put a button to prompt for an hour value manually so you can test if that's the behaviour you expect.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Barmar |
| Solution 2 |
