2

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!

Sarah Cohen
  • 706
  • 1
  • 7
  • 11
  • 1
    Nvm, you're not doing jQuery. In any case, the issue with the onclick only passing in the event remains the primary issue – Taplar Jan 02 '20 at 19:33
  • `futureValue` will be `undefined` if `yearsAmount` if less than or equal `1` because of the `for` loop – Dominik Matis Jan 02 '20 at 19:33
  • Does it help initializing futureValue like so `var futureValue = 0;`? – fh0592x Jan 02 '20 at 19:34
  • @Taplar , can you please explain what you mean? I don't understand. Thanks! – Sarah Cohen Jan 02 '20 at 19:34
  • When you assign an event handler (ex. `someElement.onclick = function`), the main thing that is passed into the method when the event happens is the event object. Not any other expected parameters you put on the callback. The first parameter will be the event. If you want to pass other things in, you either have to call the method yourself with the arguments, or use `bind()` to change what is passed in by default – Taplar Jan 02 '20 at 19:36
  • @glitch I tried that but no... – Sarah Cohen Jan 02 '20 at 19:36
  • looks like either futureValue or interest resulted in Undefined, to ensure that this does not return Undefined, i would replace the line with futureValue.toFixed(2); with let a = futureValue ? futureValue : 0; a.toFixed(2); – Ethan Harris Jan 02 '20 at 19:39

4 Answers4

9

In some cases when we bind the data directly in html, there is a chances like it may take sometime to load, so we may get the above error.

In my case I used "?" operator

for ex:- customer.price?.toFixed(2)

syed
  • 606
  • 8
  • 11
5

TypeError: Cannot read property 'toFixed' of undefined

Following code to fix the above error.

var test = 12.520;
console.log(Number(test).toFixed(2));
Vasanth Umapathy
  • 1,571
  • 14
  • 7
4

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;
};
Klaycon
  • 10,599
  • 18
  • 35
0

You need to grab the processEntries() arguments from another way. This way the only argument you gonna receive directly is the event object. Inside the processEntries function, try to do something like this instead:

var processEntries = function() {
    var investment = $('investment').value;
    var interest = $('rate').value;
    var years = $('years').value;

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

Probably you will need to format the texts correctly after you grabbing the values, try to consol.log them before calling the last function for debug purposes.

Pedro Mutter
  • 1,178
  • 1
  • 13
  • 18