Using setInterval() function to make pomodoro timer - javascript

My code is bellow, it doesn't throw errors but it stops after running ones.
I tried reviewing this codes and searching through documentation, but couldn't find anything, possibly due to my level of knowledge.
var timeNumbers = ['count','working','resting'];
var amountData = {'count':0,'working':0,'resting':0};
function fromCount(){
if(timeVa['working'] == false) return;
var amountDataNo1 = Array.from(amountData);
var dataW = setInterval(loseTimeW(1),1000);
function loseTimeW(n){
if(amountDataNo1[timeNumbers[n]] == 0){
clearInterval(dataW);
timeVa['resting'] == true;
}else{
amountDataNo1[timeNumbers[n]]--;
}
}
}

The first argument of setInterval() is the function it must invoke periodically.
The first argument you pass to setInterval() is the value returned by the call loseTimeW(1). But the loseTimeW() function does not return anything, consequently the value of loseTimeW(1) is undefined.
I guess your intention is to invoke loseTimeW() with argument 1 every 1000 milliseconds. You can achieve this easily. setInterval() accepts two or more arguments. It passes the arguments starting with the third one (if any) to the callback (argument #1) when it invokes it.
The working code is something like:
var dataW = setInterval(loseTimeW, 1000, 1);
Read more about setInterval().

Related

Function - Passing the arguments.

I have a large code base, and I am tasked to implement additional functionality. Code is Node.js - Javascript.
There is one function, and it goes like this:
function checkPeople(first, second) {
if(second) {
//do some things...
}
}
That same function is called several times, but generally it is called like:
checkPeople(first);
or...
checkPeople(first, second);
It depends what is being used for. the parameter "first" is always send regardless.
Now I have to add extra functionality to the same function but with the third parameter:
function checkPeople(first, second, third) {
if(second) {
//do some things...
}
if(third) {
//do some things
}
}
I was thinking to add third parameter to the function, wherever the function is being called (around 2 times), and check for the existance of the parameter inside the function. Which it is already done for the the parameter "second".
Is this approach valid?
Thank you
If you pass in the argument like this when you call the function, using null as the second argument, it will not call the second. Assuming that is what you are trying to do. checkPeople(first, null, third)
I'm going to be making an assumption here, but since the function is called checkPeople i'm going to assume you're doing the same check for every person (for instance: check for every person if he... exists?)
If that is the case:
function checkPeople()
{
var people = Array.prototype.slice.call(arguments);
return people.map(function(person) {
return person == 'eric'; // only eric is a person today
});
}
Now, you can do this:
var results = checkPerson('eric','peter','james'); // [true, false, false];
var result = checkPerson('eric'); // [true]
var result = checkPerson('james'); // [false]
If there are actually different checks for a first, second, and third parameter, then you indeed still have to implement the if (second) { .. } checks.

Javascript - Math.random as parameter

I asked this before, but a little vague and poorly worded.
I have a object that takes in Actions and puts them into a stack that it goes through over time. It performs the first Action in the stack until it's done, then it performs the second, and so on. There is a RepeatAction that can take in an array of other Actions and perform them a number of times in a similar fashion. (.repeat() simply puts a new RepeatAction into the objects stack.
Take this for example:
object.repeat(10,[new LogAction(Math.random())]);
Given that LogAction only takes in a parameter and logs it out. When the object's repeat function gets called it will put 10 LogActions into its stack, but they will all log the same number. What I'm looking for is a way that it will log a different number all 10 times.
You may say just pass in Math.random as a function, but then what if I want to pass in 4 * Math.random()?
Any help?
The code needs to invoke a function (later) to get a different value. e.g.
// pass in the `random` function - do not get a random number immediately!
object.repeat(10, [new LogAction(Math.random)])
// create and pass in a custom function that uses `random` itself
var rand4 = function () { return Math.random() * 4 }
object.repeat(10, [new LogAction(rand4)])
Since "LogAction" is not disclosed, I'll make a simple example to work with the above.
function LogAction (arg) {
this.execute = function () {
// If the supplied argument was a function, evaluate it
// to get the value to log. Otherwise, log what was supplied.
var value = (typeof arg === 'function') ? arg() : arg;
console.log(value);
}
}
Reading through How do JavaScript closures work? will likely increase the appreciation of functions as first-class values, which the above relies upon.
You may say just pass in Math.random as a function,
Yes, I would.
but then what if I want to pass in 4 * Math.random()?
Then in place of Math.random, use
function() { return 4 * Math.random(); }
You can pass function which returns result of random:
object.repeat(10,[new LogAction(function(){return Math.random();})]);
And in LogAction function you simply need to check if argument is a function:
function LogAction(arg){
var value = arg&& getType.toString.call(arg) === '[object Function]' ? arg() : arg;
//log value
}

Delay a For Loop

I am trying to create a FOR loop that removes an element every 1000ms instead of rushing instantaneously through the array and perform the operations.
I am doing this for reasons of performance since going normally through the loop freezes my UI.
function removeFunction (i,selected) {
selected[i].remove();
}
function startLoop() {
var selected = paper.project.selectedItems;
for (var i = 0; i < selected.length; i++) {
if (selected[i].name === "boundingBoxRect") continue;
setTimeout(removeFunction(i,selected),1000)
}
}
It seems that the selected[i].remove() method is getting called without any delay. Why is that? Since I have set a Timeout of 1000ms shouldn't the items get removed with 1000ms interval between each?
Note
In the code above, I am skipping an item called boundingBoxRect since I don't want to remove that. Just stating this so there is no confusion
Simply turn it into a recursive function:
function removeFunction (i, selected) {
// If i is equal to the array length, prevent further execution
if (i === selected.length)
return;
// Remove ith child of selected array
selected[i].remove();
// Trigger same function after 1 second, incrementing i
setTimeout(function() {
removeFunction(++i,selected)
}, 1000);
}
// Trigger the function to begin with, passing in 0 as i
removeFunction(0, paper.project.selectedItems);
Here's a JSFiddle demo (using console.log instead of selected[i].remove(), as you haven't provided a definition for that function);
It seems that the selected[i].remove() method is getting called without any delay. Why is that?
Because that's what you're telling it to do. setTimeout(removeFunction(i,selected),1000) calls removeFunction immediately and passes its return value into setTimeout, exactly the way foo(bar()) calls bar and passes its return value into foo.
You can get the effect you want by using a builder function:
setTimeout(buildRemover(i,selected),1000);
...where buildRemover is:
function buildRemover(index, array) {
return function() {
removeFunction(index, array);
};
}
Note how buildRemover creates a function that closes over the index and array variables. Then it returns a reference to that function, which is what gets scheduled via setTimeout. When the timeout occurs, that generated function is called, and it calls removeFunction with the appropriate values.
You can also do something similar using ES5's Function#bind:
setTimeout(removeFunction.bind(null, i, selected),1000);
Function#bind returns a new function that, when called, will call the original (removeFunction above) use the given this value (null in our example) and arguments.

Cant run code and function call passed as string inside settimeout

I want to run code using settimeout.
I have this function:
function passing_functions(thefunction)
{
var my_function ="res="+thefunction+ "(); if (res==true){another_function} "
and on this call :
passing_functions("load_database");
I have this string:
res = load_database();if (res==true){another_function}
Ok, I'm unable to use it inside settimetout
settimeout(function() {my_funtion},100}
settimeout(function() {my_funtion()},100}
settimeout(eval(my_funtion),100}
settimeout(my_funtion),100}
settimeout(my_funtion()),100}
etc ---
I have always an error or nothing....
Also I have tried to use "this." as prefix for "thefunction" without success.
Could anybody help me ? What I'm doing wrong ?
Thanks
NOTE:
(I want to create an array of things to be executed.
I could use passing_functions(load_database); but then I receive all the code instead the function. This is because by now I'm using string to pass the code.
)
All your "function calls" end with a } instead of a ) or have the closing ) somewhere in between. The signature is setTimeout(func, time), i.e. the function accepts two arguments, another function and a number. The arguments are put between the (...) and separated by commas. Assuming that my_funtion is actually a function, setTimeout(my_funtion, 100) will be valid.
However it seems you are trying to run JavaScript code that is inside a string. Don't do that. JavaScript is a powerful language where functions are first class citizens. So instead of passing the name of the function and build a string, just pass the function directly:
function passing_functions(thefunction) {
setTimeout(
function() { // first argument: a function
var res = thefunction(); // call the function passed as argument
if (res) {
// I assume you actually want to *call* that function
// just putting another_function there doesn't do anything
another_function();
}
},
100 // second argument: the delay
);
}
// the function load_database must exist at the time you pass it
passing_functions(load_database);
Whether or not this is what you want I cannot say, but it should give you an idea how to properly solve your issue.

Setting a JavaScript function as a parameter for use with another function?

I'm learning lots of javascript these days, and one of the things I'm not quite understanding is passing functions as parameters to other functions. I get the concept of doing such things, but I myself can't come up with any situations where this would be ideal.
My question is:
When do you want to have your javascript functions take another function as a parameter? Why not just assign a variable to that function's return value and pass that variable to the function like so:
// Why not do this
var foo = doStuff(params);
callerFunction(foo);
//instead of this
callerFunction(doStuff);
I'm confused as to why I would ever choose to do things as in my second example.
Why would you do this? What are some use cases?
Here's yet another example. Does some formatting operations on an array:
function pctFormatter(num) {
return num + '%';
}
function centsFormatter(num) {
return num + '.00';
}
function formatThisArray(array, formatter) {
var output = [];
for(var i = 0; i < array.length; i++) {
output.push( formatter(array[i]) );
}
return output;
}
formatThisArray([1,2,3], pctFormatter);// returns ['1%', '2%', '3%']
formatThisArray([1,2,3], centsFormatter);// returns ['1.00', '2.00', '3.00']
Handlers/listeners are a good example.
More generally, you can pass a function f as a parameter to function g when you don't know yet if g will need to call f, how many times it will need to call it, and/or with which parameters.
Examples:
sort algorithms: comparison function
regular expressions: replace function
callbacks (e.g. event handlers)
You'd do it when you don't have the params to pass, but the callerFunction() does.
A callback to an AJAX request is one use case.
function myCallback(response) {
// do something with the response
}
myAJAX('http://example.com/foo.json', myCallback)
This lets myAJAX to the work of making the request, and waiting for the response. Then it invokes myCallback and passes it the response when that response finally arrives.
// Why not do this
var foo = doStuff(params);
callerFunction(foo);
//instead of this
callerFunction(doStuff);
First example will run the function doStuff with params and the assign the result to foo. callerFunction will be called with parameter foo (which is now a result of dooStuff);
Second example will call callerFunction and pass doStuff as a parameter. The callerFunction might or might not call the doStuff.
Well, sometimes you don't know who the caller of a function will be until it's called - this precludes passing pre-calculated values.
A couple of examples that spring to mind are:
(a) setTimeout or setInterval - you want to call a specific function after a specified period, either one-shot, or repeatedly. If the function called returned a value that had a dependance on time, there are instances where you couldn't possibly pre-calculate the value - it needs to be done at the scheduled time. So, we tell the functions which of our own functions to call at the specified time.
(b) when loading (or at least attepmpting to) various resources. We can give the element a function that is to be executed when loading is successful, and another when it fails. You don't actually know when the effort to load a resource has finished until either of these two (user-supplied) functions are called. In the case of many resources, this is where you increment the counters that maintain the number of successful/failed load attempts.
(c) the NodeList returned by calls to getElementsByClass or getElementsByTagName. It's not an actual (javascript native) Array object. As such, you can't call the forEach method on it, like you can with an array. To get around this, I use the following helper function:
// getElementsByTagName, getElementsByClass - both return a NodeList
// it is accessed in the same way as an array - with the [] operators, but it's
// not an array object - this is a function that allows us to still iterate through it
// in much the same way.
function forEachNode(nodeList, func)
{
var i, n = nodeList.length;
for (i=0; i<n; i++)
{
func(nodeList[i], i, nodeList);
}
}
This allows me to get a list of nodes and then call some user-defined function on each of them. In use, it looks like this:
var allAnchors = document.getElementsByTagName('a');
forEachNode(allAnchors, showNodeTextVal);
function showNodeTextVal(curElem, curIndex, origList)
{
alert(curElem.innerText);
}
Or more simply:
var allAnchors = document.getElementsByTagName('a');
forEachNode(allAnchors, function(curElem){alert(curElem.innerText);} );
This is a much clearer, less error-prone situation than it would be if we didn't use this helper function. To achieve the same functionality, we'd need to code the following:
var nodeList = document.getElementsByTagName('a');
var i, n = nodeList.length;
for (i=0; i<n; i++)
{
alert(nodeList[i].innerText);
}
Most common case is handlers in JQuery:
function clickHandler(e){
// handle click on e.Target
}
$("#button").click(clickHandler);
$(function(){
// do ready state initialization
});
callerFunction(doStuff);
with this code you give a "pointer" of the function doStuff to the function callerFunction
you can use it like this:
function callerFunction(doStuff) {
var x = doStuff(...);
...;
}
you can so use the function in the function and not only the return value of doStuff.
greetings!
When do you want to have your javascript functions take another
function as a parameter?
It's useful for callbacks for example:
function add( a, b, callback ) {
callback( a, b );
return a + b;
}
function added( a, b ) {
alert('You just added two numbers: '+ a +' and '+ b);
}
alert( add( 1, 2, added ); // Will alert the message and then the result.
This a very simple example but it's very useful with asynchronous functions so you can run code after it has finished without interrupting the script.
You need to pass functions themselves, not return values, when you want to have your code really deal with functions as functions - code to execute. Consider this pseudo-code example:
function saveToLocalStorage(data) {...//saves to local storage}
function saveToServer(data) {...//saves via AJAX to server}
function saveToAmazonS3(data) {.../saves to Amazon S3 }
function multiSave(data, saverFunctions) {
saverFunctions.forEach(function (saverFunction) {
saverFunction(data);
});
}
multiSave({user: "tim"}, [saveToLocalStorage, saveToServer, saveToAmazonS3]);
In this case, I want the actual functions themselves to be passed around and for other code to later invoke them. When we do this, a function such as multiSave is called a higher-order function because it deals with other functions directly. Because of the way multiSave works, I can easily put some checkboxes in the UI next to local/server/S3 and allow the user to choose where their data goes in a way that would be less elegant if I was unable to pass functions around as arguments.
When you're passing a function as an argument, that argument is not the return value of that function, but it's the function itself, you can call it as much as you like, with any argument you like, or you can assign it to an event. You say you want some practical use cases, here's a short list of very common situations, all requiring a function to be passed as an argument.
Let's take a look at your average jQuery code, and count the number of times where a function is passed as an argument:
$(document).ready(function()//<-- 1
{
$('#foo').on('click',function()//2
{
});
$.each(something,function()//3
{});
//and so on
});
If you don't use jQuery, then try event delegation
document.body.addEventListener('click',function(e)
{
e = e || window.event
console.log('This function was passed as an argument to the addEventListener method');
},false);
Or even the simple Array.prototype.sort function (/method):
anArray.sort(function(a,b)
{
return (a > b ? 1 : -1);
});
Or in cases where you need to make an ajax call, instead of creating a new XMLHttpRequest object on the spot, you might want a single function that sets the xhr object up, and pass the url, data and onreadystatechange callback as arguments:
function makeXHR(url,data,callback)
{
try
{
var xhr = new XMLHttpRequest();
}
catch(e)
{
//etc...
}
xhr.onreadystatechange = callback;
}
makeXHR('some/url','foo=bar',function()
{
if (this.readyState === 4 && this.status === 200)
{
//do stuff
}
});
In all of these examples, I've created the functions in-line, of course referencing a function (by just passing its name) works just fine, too:
makeXHR('some/url','foo=bar',defaultXhrCallback);
These are just a few of thousands of use cases where you can/have to pass a function as an argument to another function

Categories