Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Timothy Tuite
Timothy Tuite
5,429 Points

Function not defined onclick

I've defined a function that I'm using for calculations on a web page here

<script>
function setValues() {
  var a, b, c, d, e;
  a = Number(document.getElementById("GE").value);
  b = Number(document.getElementById("TPPIC").value);
  c = Number(document.getElementById("PESF").value);
  d = Number(document.getElementById("PPSF").value);
  e = Number(document.getElementById("extra").value);
}
  function gradefunction() {
    setValues();
    var ab = a*b
    var ce = c+e
    var bd = b-d
    var result = ((ab-ce)/bd)*100;}
</script>

then in my html code i try to run it here

<button id="calculate" type="button" onclick="gradefunction()">Calculate</button><br>

and thats where I get the error that its not defined. My concern is that the function is not globally available. What does that mean I'm not familiar with javascript. Also how do i fix it.

1 Answer

Hugo Paz
Hugo Paz
15,622 Points

Hi Timothy,

In javascript each function has its own scope, so if you declare a variable inside a function, it is only available to that function or functions nested inside it.

While you get the values from the html, you are not passing them to gradeFunction, so gradeFunction is unaware of a, b, c, d and e. Now there are a few options, the easier one is to declare the variables a, b , c, d and e outside of the functions, making them global. This is not a good solution because it pollutes the global scope.

Another option is to call the gradeFunction inside setValues, using the variables as arguments, changing the onclick call to setValues

<html>
<body>
<input type='number' id='GE' value='0'></br>
<input type='number' id='TPPIC' value='0'></br>
<input type='number' id='PESF' value='0'></br>
<input type='number' id='PPSF' value='0'></br>
<input type='number' id='extra' value='0'></br>
<button id="calculate" type="button" onclick="setValues()">Calculate</button><br>

<script>
function setValues() {
  var a, b, c, d, e;
  a = Number(document.getElementById("GE").value);
  b = Number(document.getElementById("TPPIC").value);
  c = Number(document.getElementById("PESF").value);
  d = Number(document.getElementById("PPSF").value);
  e = Number(document.getElementById("extra").value);
  gradefunction(a, b, c, d, e);
}
  function gradefunction(a, b, c, d, e) {
    var ab = a*b
    var ce = c+e
    var bd = b-d
    var result = ((ab-ce)/bd)*100;
    console.log(result);
}
</script>
</body>
</html>

Finally you can store the values in an array and and return it when you call the setValues function

<html>
<body>
<input type='number' id='GE' value='0'></br>
<input type='number' id='TPPIC' value='0'></br>
<input type='number' id='PESF' value='0'></br>
<input type='number' id='PPSF' value='0'></br>
<input type='number' id='extra' value='0'></br>
<button id="calculate" type="button" onclick="setValues()">Calculate</button><br>

<script>
function setValues() {
  var values = [];
  values.push(Number(document.getElementById("GE").value));
  values.push(Number(document.getElementById("TPPIC").value));
  values.push(Number(document.getElementById("PESF").value));
  values.push(Number(document.getElementById("PPSF").value));
  values.push(Number(document.getElementById("extra").value));
  return values;
}
  function gradefunction() {

    var values = setValues();
    console.dir(values);
    var ab = values[0]*values[1]
    var ce = values[2]+values[4];
    var bd = values[1]-values[3];
    var result = ((ab-ce)/bd)*100;
    console.log(result);
}
</script>
</body>
</html>