Raiding_rider
Raiding_rider

Reputation: 33

javascript function is undefined but my script is being loaded

So I'm trying to master JavaScript and to practice I'm trying to make a reaction time test. The idea is very simple: you click on a button and after a random period of time the background changes colour and then you have to click on a second button which calls on a function that calculates your reaction time. Here is my JavaScript code:

function start(){
    console.log(start);
    var rndnr = (Math.round(Math.floor(Math.random() * 5) + 1)) * 1000);
    setTimeout(function timeout() {
      document.bgColor="ffff00";
      start = new Date();
    }, rndnr);
}

function stop() {
    var onclick = new Date();
    var time = onclick-start;
    var total;
    var avg;
    var count = 1;
    document.getElementById("try 1").innerHTML = time;
    total = total + time;
    avg = total / count;
    count = count + 1;
    document.getElementById("avg1").innerHTML = avg;
}

and these are my buttons:

<button id="button" onclick="start()" >start</button>
<button onclick="stop()">stop</button>

When I try to execute the script I get an error in my console log which says this: ReferenceError: start is not defined. Where have I gone wrong?

Upvotes: 3

Views: 20341

Answers (6)

Jason Cust
Jason Cust

Reputation: 10909

You have quite a few typos in your code as well as some naming collisions and scope issues. This is your original code (aside from renaming stop to stopF since stop is a global function in a browser.

function start() {
  console.log(start);
  // THE REFERENCE ERROR STEMS FROM THIS LINE PREVENTING THE FUNCTIONS
  //  FROM BEING DEFINED
  var rndnr = (Math.round(Math.floor(Math.random() * 5) + 1)) * 1000);
  setTimeout(function timeout() {
    document.bgColor = "ffff00";
    start = new Date();
  }, rndnr);
}

function stopF() {
  var onclick = new Date();
  var time = onclick - start;
  var total;
  var avg;
  var count = 1;
  document.getElementById("try 1").innerHTML = time;
  total = total + time;
  avg = total / count;
  count = count + 1;
  document.getElementById("avg1").innerHTML = avg;
}
<button id="button" onclick="start()">start</button>
<button onclick="stopF()">stop</button>
<div id="try 1"></div>
<div id="avg1"></div>

If you click "Run code snippet" you will notice an error in the console:

 Uncaught SyntaxError: Unexpected token )

Because of this error, neither start nor stopF are defined. Therefore when the start button is clicked the inline JS would be evaluated and then attempt to find a non-existent start function resulting in a ReferenceError. Similarly if the stop button is clicked it will also log a ReferenceError for stopF.

Correcting some of the issues in the code gives:

// You need to have a way of referencing the `start` variable (now `startTime`)
//  between the `start` and `stop` functions.
// You also need to be able to keep state for `total` and `count` between
//  subsequent calls to `stop`
// These issues can be solved by using scope variables
//  (here they are in the IIFE scope of the wrapper function)
var startTime;
var total = 0;
var count = 0;

// You had a name collision here within the scope of `start`
//  you also had attempted to use a variable named `start`
// Now the variable is called `startTime`
function start() {
  // You had an extra ')' in your expression assignment for `rndnr`
  var rndnr = (Math.round(Math.floor(Math.random() * 5) + 1) * 1000);
  setTimeout(function timeout() {
    document.bgColor = "ffff00";
    startTime = new Date();
    // Since setTimeout is an async function console.log would be undefined
    //  until this function runs
    console.log(startTime);
  }, rndnr);
}

function stop() {
  var onclick = new Date();
  var time = onclick - startTime;
  var avg;
  total += time;
  avg = total / ++count;

  // You shouldn't include spaces in ID values as it can be confusing
  //  if this was intentional
  document.getElementById("try1").innerHTML = time;
  document.getElementById("avg1").innerHTML = avg;
  document.bgColor = "ffffff";
}
<button id="button" onclick="start()">start</button>
<button onclick="stop()">stop</button>
<div id="try1"></div>
<div id="avg1"></div>

Upvotes: 3

HolloW
HolloW

Reputation: 730

Edited:

Here is a working version of your code (only the stop button needs the tags "try 1" and "avg")

http://jsfiddle.net/2q84yvzu/

The problem was on the extra ) on:

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000);

This is the correct version:

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000;

I changed the way of you bind the events to the elements, is not a good practice to embed the events inline. Instead try the next approach:

document.getElementById('start').onclick=function(){start();};
document.getElementById('stop').onclick=function(){stop();};

For more info on this, here is another question:

Inline onclick JavaScript variable

Upvotes: 1

Vladimir
Vladimir

Reputation: 352

You need to rename variable start inside setTimeout function, because you override function start with date value after the first call of start() function.

function f(){
    setTimeout(function(){ f = 1; }, 1000);
}

console.log(f); // function

f();

setTimeout(function(){ 
  console.log(f); // 1
}, 1100);

Upvotes: 0

Sebastian Nette
Sebastian Nette

Reputation: 7832

To ensure that the document knows about the start function, do something like:

window.start = function start(){ ... };

Or make sure to load your script before the handlers are assigned.

Secondly, don't try to set a value to start, since start refers to a function. Use startTime or another variable instead.

startTime = new Date();

Upvotes: 3

Ben Zhong
Ben Zhong

Reputation: 9

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000);

syntax error,it should be

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000;

Upvotes: 1

Kbi
Kbi

Reputation: 384

console.log(start); 

is wrong

It has to be

console.log("start"); 

or you have to create the variable start

var start = "put anything in here";
console.log(start);

Upvotes: -2

Related Questions