javascriptonclicksyntax-errortofixed

Uncaught TypeError: Cannot read property 'toFixed' of undefined


I know that others have had this error thrown but I think I have some sort of syntax problem that's causing this to happen for me. If you can find it I would be grateful. I'm new to JavaScript and have been staring at this simple program for an hour.

Here's the JavaScript:

"use strict";
var $ = function(id) {
    return document.getElementById(id);
};

var calculateFV = function(investmentAmount, interestRate, yearsAmount) {
    var futureValue;

    //get the future value after the amount of years entered
    for (var i = 1; i <= yearsAmount; i++ ) {
        var interest = futureValue * interestRate / 100;
        futureValue = futureValue + interest;
    }

    return futureValue.toFixed(2);
};

var processEntries = function(investmentAmount, interestRate, yearsAmount) {
    var investment = investmentAmount;
    var interest = interestRate;
    var years = yearsAmount;

    var futureValue = calculateFV(investment, interest, years);
    $("calculate").value = futureValue;
};

window.onload = function() {
  $("calculate").onclick = processEntries;  
};

And here's the HTML:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Future Value Calculator</title>
 <link rel="stylesheet" href="future_value.css">
 <script src="future_value.js"></script>
</head>

<body>
 <main>
     <h1>Future Value Calculator</h1>

     <label for="investment">Total Investment:</label>
     <input type="text" id="investment"><br>

     <label for="rate">Annual Interest Rate:</label>
     <input type="text" id="rate">%<br>

     <label for="years">Number of Years:</label>
     <input type="text" id="years"><br>

     <label for="future_value">Future Value:</label>
     <input type="text" id="future_value" disabled><br>

     <label>&nbsp;</label>
     <input type="button" id="calculate" value="Calculate"><br>      
 </main>
</body>
</html>

Thanks so much!


Solution

  • futureValue is only given a value in the event that the i <= yearsAmount loop executes at least once. However, it isn't executing even once: this is because yearsAmount will always be undefined. Why? Let's take a look at how this function gets called:

    var futureValue = calculateFV(investment, interest, years);
    

    This is where calculateFV is called, so years must be undefined. years is just the parameter yearsAmount from your processEntries header:

    var processEntries = function(investmentAmount, interestRate, yearsAmount) {
    

    So we know processEntries got called with an undefined third argument.

    This line is the culprit:

    $("calculate").onclick = processEntries;
    

    An element's onclick event only gets called with one argument: the event object. The code doesn't know you want it to pass the values of the input boxes labeled investment, interest, and years. So, instead of three numbers, you get one event object and two undefined values. Instead you need to select these elements and get their values in processEntries yourself.

    That would look something like this:

    var processEntries = function(event) { //notice only the event will be given
        //text box values will be strings, so convert to number with Number()
        var investment = Number($("investment").value);
        var interest = Number($("rate").value);
        var years = Number($("years").value);
    
        var futureValue = calculateFV(investment, interest, years);
        $("calculate").value = futureValue;
    };