Hi everyone,
I'm working on implementing a timer countdown logic using JavaScript in a web block. However, I'm encountering an issue where, after initially passing a date and time value to the block, if I update the value, two countdowns run simultaneously. I'm looking for a solution to stop the timer countdown of the first passed value when a new value is set.
AppLink: https://personal-w1gn98aj.outsystemscloud.com/SerealizationJSONExercise/Customers?_ts=638435259723412856
Hey @Hasnain Khalid
To destroy The Interval use clearInterval();
Make a global variable
use that variable to set your interval
now to destroy it do
i have attached OML you can view
Hope this helps
Regards,Kshitij
Thank You so much, It worked for me
@Kshitij Raheja ,
although a global variable might work in a poc / demo, it is not best practice / advisable in real applications. Even simply putting the same block on a screen twice will already break your code.
@Hasnain Khalid ,
Dorine
I see, thanks for your advice but @Dorine Boudry wouldn't OnDestroy remove the interval on its own with the block also what would be the output parameter type of the javascript will it be object
No, the fact that you created a timer from inside an action of a block, doesn't mean it will be stopped once the block stops to exist.
The data type can be text.
Okay thanks
@Dorine Boudry Can you please do it in a demo OML file as I tried but didn't succeed
what part are you struggling with ?
I made the OML for you with the logic thanks, @Dorine Boudry it worked perfectly
Let me know if that solves your issues
Yeah I tried this one , but it is showing the error message "variable is not defined"
I also tried oml of Kshitij, and it works fine.
In a real application, I might maybe check if IntervalVar has a value, before trying to clear it, but it doesn't fail if you don't.
im getting the error while using this method and also not working
yes, but it works for us, so you'll have to share screenprints of what exactly you are doing if you want us to be able to help.
It sounds like you are not referencing your input parameter correctly, compare what you do in detail to what Kshitij is doing in his example, there has to be a difference.
What is this newTimerId variable, where do you define it, and where do you use it ?
Replying to Dorine Boudry's comment on 15 Feb 2024 11:30:48
I have successfully achieved the desired results, let me show you the approach that I have used:
so what all I did, I declared the "newtimerId" variable within the setInterval script and stored the result in one output parameter of the same script. Subsequently, I assigned the output parameter's result to a local variable. Finally, I utilized and cleared this local variable within the onDestroy event of the block using clearInterval function.
below is the OML file , javascript code and the screenshot of the logic , you can check it and give me a feedback.
I would appreciate your feedback
Thank you
Create interval script code:
//clear all interval if exist
window.clearInterval($parameters.OldTimerId);
//set interval
const newTimerId = window.setInterval( ()=>
{
// var endTime = new Date("29 June 2020 9:56:00 GMT+01:00");
var endTime = new Date($parameters.EndDateTime);
endTime = (Date.parse(endTime));
console.log("endtimed",endTime)
var now = new Date();
now = Date.parse(now);
console.log("cur",now)
var timeLeft = endTime - now;
console.log("timeleft",timeLeft)
let days = Math.floor(timeLeft / (1000 * 60 * 60 * 24));
let hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((timeLeft % (1000 * 60)) / 1000);
console.log(days,hours,minutes,seconds);
if (days < 0 || days === null) { days = 0; }
if (hours < 0 || hours === null) { hours = 0; }
if (minutes < 0 || minutes === null) { minutes = 0; }
if (hours < "10") { hours = "0" + hours; }
if (minutes < "10") { minutes = "0" + minutes; }
// if (seconds < "10") { seconds = "0" + seconds; }
document.getElementById($parameters.Days).innerHTML = days
document.getElementById($parameters.Hour).innerHTML = hours
document.getElementById($parameters.Minute).innerHTML = minutes
if (timeLeft <= 0) {
console.log("insideif")
document.getElementsByName($parameters.reviewTime).style.visibility = 'visible'
$parameters.isTimeout=true
clearInterval(newTimerId);
document.getElementById("$parameters.Days").innerHTML = "EXPIRED";
document.getElementById("$parameters.Hour").innerHTML = "EXPIRED";
document.getElementById("$parameters.Minute").innerHTML = "EXPIRED";
}
},1000);
$parameters.NewTimerId = newTimerId;
Clear Interval Script:
clearInterval($parameters.TimerId);
glad you found the problem, it was probably a javascript naming mistake, right ? I saw you were using a variable called NewTimerId2 in an earlier version.
So, though this might work now, it is really not the approach I would take, and if your company is paying for such a beautiful platform like OutSystems, it really is a shame to do stuff in Javascript that you could also do in Low Code.
So my approach would be to only use Javasript to create and clear the interval, but use Outsystems regular code for everything else. What you are doing now, manipulating the DOM directly, is a real eyesore.
It is also a mistery to my why you have those 2 events on that webblock, what is supposed to happen there ?
I'll take some time tonight to modify your webblock into how I would do it.
Also : you are showing minutes : do you really need to recalculate every second ?
those two events are for other purposes .