Working on my own Javascript countdown timer/ Pomodoro technique - javascript

Since I have been teaching myself how to code in JavaScript by watching tutorials on YouTube and reading Head First Javascript book, I decided to set my own challenge by building something that has been quite effective to me - The Pomodoro technique! I have been using this technique since I have started learning JavaScript. And whilst I was thinking of a JavaScript coding challenge that involves arrays, functions, DOM, etc. I thought why not the Pomodoro technique that can have an array of activities to do during my 5-minute break, a function for the 25 and 5-minute timer and then style it using HTML and CSS. Anyway, here is my code so far...
<script>
function startTimer() {
var timer = document.getElementById("myTimer").innerHTML;
var arr = timer.split(":");
var hour = arr[0];
var min = arr[1];
var sec = arr[2];
if (sec == 0) {
if (min == 0) {
if (hour == 0) {
alert(pushup());
window.location.reload();
return;
}
hour--;
min = 60;
if (hour < 10) hour = "0" + hour;
}
min--;
if (min < 10) min = "0" + min;
sec = 59;
}
else sec--;
if (sec < 10) sec = "0" + sec;
document.getElementById("myTimer").innerHTML = hour + ":" + min + ":" + sec;
setTimeout(startTimer, 1000);
function pushup() {
var minBreak = ["Do 5 push ups!", "Do 10 push ups!", "Do 15 push ups!",
"Do 5 sit ups!", "Do 10 sit ups!", "Do 15 sit ups!",
"Clean room!", "Do laundry!", "Walk dog!" ];
var rand1 = Math.floor(Math.random() * minBreak.length);
var phrase = minBreak[rand1];
alert(phrase)
};
};
</script>
</head>
<body onload="startTimer();">
<p id="myTimer">00:00:10</p>
</body>
I did this step by step creating the pushup function first, which was easy to do, setting alerts on each step so I knew I was going on the right track too. However, startTime function is a copy on a YouTube video. As much as I would have loved to figure this out myself I was struggling hard to set a timer in the browser! The only successful way I can do was use the setInterval method. However, the video was only one minute long and it does not explain how it works. I made sure I gone through line to line to understand how it works, the .split method, why multiple of if statements, etc. Wrote notes down and make sure I understood. Now, when the timer goes off at 10 secs it alerts one of the minBreak chores in random, success! BUT then shows another alert saying "The page says undefined" why is this? And (because I am new to creating this) how would you have written this code? I am thinking to have multiple variables of different chores. So, var pushup will have an array of 1 push up, 2 push up and so on. var situp will have an array of 1 situp, 2 situp and so on. What statements or methods should I use so the math.random can pick one of many different variables arrays randomly instead of being all in one. Not really asking for you to show me a code of how it's done but a route of using for statements, or while, or ifs, etc. sorry if doesn't make sense.. I am new to this! But just trying to make something up on the way and challenge myself, and question myself. but at the same time need a mentor/ teacher to show me the way.

You are getting the undefined message, because you have twice an alert. The second one uses a function return value to display, but that function does not return anything, hence undefined:
alert(pushup());
So the function pushup performs itself an alert, which is like you want it. But then the function returns to the above statement, where the function's result is displayed in an alert. It is undefined.
So you can fix this by just calling the function:
pushup();
As far as I understand this was the only issue to be fixed.

Related

Discord.js Set Interval function not activating. Need confirmation of cause

I am currently having an issue with the setinterval function and was wondering if anyone could help. So oddly enough, it works for short intervals like 10 or 20 seconds but when I scale it to a day or half a day it fails to run. I'm on version 11.5.1 of discord.js
bot.setInterval(function(){
var Holiday = new Date();
var month = Holiday.getMonth()+1;
var day = Holiday.getDate();
var check = month+'/'+day;
var greeting = "";
for(var i = 0; i < Events.length; i++){
if(check == Object.keys(Events[i]) && check != "12/25"){
greeting = "Happy "+Object.values(Events[i]);
}
if(check == "12/25"){
greeting = "Merry Christmas";
}
}
for(var j = 0; j < c.length;j++){
var channel = bot.channels.get(c[j]);
if(greeting != ""){
channel.sendMessage(greeting);
}
//channel.sendMessage('test');
}
}, 3600000,)
This is the function in the ready event. Events is a json file with an array of key value pairs. c is an array with channel ids. so in the json file I have a test date that when I ran for the current day it would work, but when I change the day to the next and then wait for that time to come, nothing happens but the time should have passed and the variables should have all been reset so any ideas? Also, I have the bot hosted on glitch sending itself ping requests as well as using uptime robot which has indicated there has not been a down for 60 hours. The only reason I could think of for the cause is that maybe glitch puts the bot to sleep for a split second and it causes the interval to constantly reset, but then that would mean the pings and uptime robot are having no effect. Also, if anyone has a clever work around I would be grateful. The best I could do was just have a command that does this.
maybe because you didn't break function at the end like this
}
//channel.sendMessage('test');
}
}, 3600000);
and maybe that comma making the value act as an integer and more value going to be put in there.
Since I've updated to the new version of the library things have changed. However, this was long ago and I was hosting on glitch at the time, and that ended up being the problem. Glitch will still put to sleep the bot even if you are pinging it with uptime robot as they prevent ping spam.

Decrement a variable once a day - Javascript

I'm trying to decrement a variable once a day. I have written the following code for that.
var counter = 10; //any value
setInterval(function() {
counter = counter - 1;
}, 86400000);
Is there a better or efficient way to achieve the same thing ?
P.S : - I do not wish to use any libraries.
The only thing I see you miss is to set the initial value of counter variable.
I would write:
var counter = 1000; // or any useful value
setInterval(function() {
--counter;
}, 24 * 60 * 60 * 1000); // this is more self-explanatory than 86400000, and, being evaluated just once, it will have a tiny effect on the performace of the script
I don't see any problem in the way you write it. You use interval, ok, but this is not the worst evil you may do to set up the variable value.
You may think of another solution with a function which returns you the current counter.
var initialValue = 20000;
function getCounter() {
return initialValue - Math.floor(Date.now() / 1000 / 60 / 60 / 24);
}
console.log(getCounter());
The difference is that it takes the current day number starting from the UNIX time beginning. Every day the day number will be increased, so the result of the function will be decreased by 1.
But still I don't see how this solution can be better than yours.
I'm not totally sure why, but using setInterval like this makes me uncomfortable.
If I were to require this, I would use something like this approach:
var counter = 10;
var timeout = new Date();
setInterval(function(){
if(new Date() >= timeout)
{
--counter; // the action to perform
timeout = new Date(timeout.getTime() + 86400000); // update the timeout to the next time you want the action performed
}
console.log(counter);
},1000); // every second is probably way more frequent than necessary for this scenario but I think is a decent default in general
One thing that this allows is to, for example, set the next timeout to midnight of tomorrow rather than being locked in to "X seconds since the previous execution". The key is the inversion of control - the action itself can now dictate when it should next run.
Though I would probably abstract away the details behind an interface accepting a start, interval, and action.
The biggest problem in my eyes is that you have to keep this one JS process running consistently for days at a time to have it do what you need. The world is not so perfect that things don't need an occasional reboot...including the average JS process.
Personally I would store a timestamp of my starting point, then (whenever I need to know how much time has elapsed) grab a new timestamp and use it to calculate how many days it has been. That way even if something interrupts my process I can still be right where I started.
Maybe use window.localStorage to save the last time, and if it is greater than 60*60*24 (seconds in a day) set the last time to this morning/now/1:00 and then decrease the value and save it.
Example:
var d = new Date();
var mins = -(1+d.getHours())*60+d.getMinutes();
var secs = mins*60+d.getSeconds(); // total seconds passed today from 1:00
var now = d.getCurrentTime():
var lastCheck = localStorage.getItem("lastCheck");
if (!lastCheck)
{
localStorage.saveItem("lastCheck",now-secs); // beginning of today
}
var dayPassed = now - lastCheck > 24*60*60; // change to see if a day has passed
if (dayPassed)
{
// save seconds
localStorage.setItem("counter",localStorage.getItem("counter")-1);
localStorage.saveItem("lastCheck",now-secs); // beginning of today
}
It makes more sense to me to check how many days have passed since a specific date and decrement that number of days from the counter. Mostly just because I wouldn't expect anybody to leave the same page open without the need or want to reload for days on end. I would do something like this:
counter = 365; // original counter
var start = new Date(2016, 03, 20); // original date
var now = new Date();
var days = Math.floor(Math.abs(start.getTime()-now.getTime())/(24*60*60*1000))
counter -= days;
That way every time you visited the page, it would be decremented correctly. Note that this ignores any issues with leap days or time zones. The example above would have a counter of 360 for me. And then if you did expect it to be open for days, reload it automatically with:
self.setTimeout(function(){document.location.reload()}, 86400000);

Database compatible countdown

I'm looking to create a 15 min countdown that is being displayed when the button start is pushed, but that it is also accessible from different computers. Meaning it doesn't restart when you refresh, or log in in a different computer.
My logic was something like this...
$start = datetimestamp(h:i:s);
$end = datetimestampt(h:i:s) + 900 ;
$countdown = $end-$start
echo $countdown;
However, the timestamp is giving me a lot of issues, and the $countdown is not live.
I'm thinking this has to be strictly php for it to work with MySQL (so that the timestamp doesn't refresh).
I have this in JavaScript which basically is just a countdown of 15 minutes that gets activated when the button is clicked, however it does restart every time the page is refreshed or accessed from a different computer. And I can't figure out how to store a variable into a database...
var seconds = 900;
var t;
function secondPassed() {
var minutes = Math.round((seconds - 30) / 60);
var remainingSeconds = seconds % 60;
if (remainingSeconds < 10) {
remainingSeconds = "0" + remainingSeconds;
}
document.getElementById('countdown').innerHTML = minutes + ":" + remainingSeconds;
}
function countdown() {
// starts countdown
secondPassed();
if (seconds != 0) {
seconds--;
t = setTimeout("countdown()", 1000);
changeColor();
}
}
function cdpause() {
// pauses countdown
clearTimeout(t);
};
function cdreset() {
// resets countdown
cdpause();
secondPassed();
};
I appreciate any help or guidance you can give me! I've gone through some tutorials, but it doesn't match the requirements I have. If it matters I'm trying to have different timers that may start at different times and all need to be recorded an displayed.
Simple logic.
When the button is clicked, store the start and end times in the database.
When you are displaying it, use the end time and current time to display the timer. You can use the javascript to display the timer.
In this way, you will be able to show the same timer in different systems without restarting it.
To store a value in the database , google it. There are many tutorials online to help you understand inserting data into mysql database using php

using if else statements with a timer

Im trying to set up a series of if else statements using a timer. Ideally, these if else statements would display images according to real time. However, if there is a way to set up my own timer and have the images display using if else statements that would also work. Here's what I'm thinking;
if (time < 7:00) {
document.getElementById("whatever").style.display="block";
}
Please assist if anyone knows the best possible solution for this particular problem. THANK YOU!!
If you just want a condition that becomes truthy when it's earlier than 7pm:
if (new Date().getHours() < 19) { }
The getHours() method returns the hour of the day between 0 and 23.
In a timer function it would look like this:
function doMagicStuff()
{
var now = new Date();
if (now.getHours() < 19) {
}
// other conditions based on time
}
// let it run approximately every second; doesn't have to be very accurate
setInterval(doMagicStuff, 1000);

ajax/JS timed countdown?

Let me explain what I'm trying to do.
I want to make a simple box which counts down numbers at intervals I specify.
For example, I'd like to set it to start at 150, and then I want to set it to drop by 15 every 30 seconds.
Is this possible with AJAX/Javascript? If so, could someone point me in the right direction?
Would really appreciate any help on this script, been Googling for hours now! :(
Cheers
Kieran
Have a look at the setTimeout or setInterval methods, they allow you to execute a function after a specified number of milliseconds (1000ms = 1second). Use that, to call a function that keeps dropping the number and writes it to a HTML element to the user can see it.
this isn't tested, but i hope it shows you the way to go.
var start = 150;
var drop = 15;
var interval = 30;
function countdown(){
document.getElementById('mybox').innerHTML = start;
start-=drop;
window.setTimeout("countdown",interval*1000);
}
countdown();
You may use jQuery to do that, see http://keith-wood.name/countdown.html -> tab Callbacks
Keep in mind that 30 seconds in my browser are not necessarily equal to 30 seconds in your browser. It depends on the workload of the browser.
The time difference is minor for a short time but can increase over a long time. The times will drift apart. If the times must not be equal (or nearly equal) between two visitors than such simple solution should be fine.
We had once a problem to introduce a live clock / countdown in one of our projects. We build a script with javascript, ajax and PHP for clock synchronisation (server time was timeserver).
You should use setInterval / clearInterval which is made for this kind of tasks:
function cooldown(element, start, stop, step, delay) {
var current = start;
element.innerHTML = current;
var timer = setInterval(function () {
current -= step;
if(current < stop) current=stop;
element.innerHTML = current;
if(current == stop) clearInterval(timer);
}, delay*1000);
}
Demonstrated here : http://jsfiddle.net/PCMHn/

Categories