简体   繁体   中英

Nan error in Javascript - what am I doing wrong?

I'm attempted to learn Javascript (again) due to a new role at work and am struggling a little. As a learning exercise I'm trying to code a simple set of functions to get used to the simple skills and have come across a problem. Code is below, but I have a webpage I've built to capture some data and the pass into some simple interest calculations. Unfortunately I'm getting a Nan error when the values hit the functions and I don't know how to resolve it.

I've tried +document, parse(float) and capturing the innerhtml from the fields, but none of those worked so I'm a little stumped. I'm certain it's a typecasting issue but no idea how to resolve it.

I'm capturing the fields used in the calculations via:

 var runCalculations = new function() { this.calculateTotalPayable = function() { this.submitInitialValues(); this.simpleInterestCalc(); this.monthlyCompInterestCalc(); this.dailyCompInterestCalc(); } this.submitInitialValues = function() { //Initial loan or investment amount var initialAmount = +document.getElementById("initialAmount").value; console.log("Initial loan amount: " + initialAmount); //Interest rate var interestRate = +document.getElementById("interestRate").value; console.log("Interest rate: " + interestRate); //Tenure of loan var loanTenure = +document.getElementById("loanTenure").value; console.log("Loan tenure: " + loanTenure); } this.simpleInterestCalc = function() { var simpleInterestTotal = 0; console.log(initialAmount + interestRate + loanTenure); simpleInterestTotal = initialAmount + (initialAmount * (interestRate / 100) * loanTenure); console.log("simple " + simpleInterestTotal); } this.monthlyCompInterestCalc = function() { const monthCompInterestTotal = 0; console.log("month " + monthCompInterestTotal); } this.dailyCompInterestCalc = function() { const dailyCompInterestTotal = 0; console.log("daily " + dailyCompInterestTotal); } }
 <form id="initialValues"> <label for="initialAmount" style="margin-left: 50px"><b>Initial loan or investment amount</b></label><br> <input type="number" id="initialAmount" name="initialAmount" style="margin-left: 50px" value="0"><br> <label for="interestRate" style="margin-left: 50px"><b>Interest rate</b></label><br> <input type="number" id="interestRate" name="interestRate" style="margin-left: 50px" value="0"><br> <label for="loanTenure" style="margin-left: 50px"><b>Loan tenure</b></label><br> <input type="number" id="loanTenure" name="loanTenure" style="margin-left: 50px" value="0"><br> <br> <input type="button" style="margin-left: 50px" value="Submit" onclick="runCalculations.calculateTotalPayable()"> <input type="reset" style="margin-left: 50px" value="Reset Values"> </form>

Your variables are defined in submitInitialValues , not in simpleInterestCalc . It will work if you move the variable declarations outside of the function. Please learn about scope in JavaScript before you continue.

The reason why it didn't simply crash with errors like 'initialAmount' is not defined is that for legacy reasons, HTML elements with IDs are exposed as global variables by default unless you define your own with the same name, so inside of simpleInterestCalc your variables were actually referencing the corresponding HTML elements themselves and not their values.

Thank you to people for the pointers. I've managed to get something more usable. Any constructive feedback is welcome (mainly because I know any proper coder will look at what I've done and probably wince!)

const runCalculations = new function(){

this.calculateFinalValues = function(){

    //Initial loan or investment amount
    const calcInitialAmount = +document.getElementById("initialAmount").value;
    //Interest rate
    const calcInterestRate = +document.getElementById("interestRate").value;
    //Tenure of loan
    const calcLoanTenure = +document.getElementById("loanTenure").value;

    calcSimple(calcInitialAmount,calcInterestRate,calcLoanTenure);
    calcAnnualCompound(calcInitialAmount,calcInterestRate,calcLoanTenure);
    calcMonthlyCompound(calcInitialAmount,calcInterestRate,calcLoanTenure);
    calcDailyCompound(calcInitialAmount,calcInterestRate,calcLoanTenure);

    function calcSimple(calcInitialAmount,calcInterestRate,calcLoanTenure){
        let simpleFinalTotal = 0;
        simpleFinalTotal = calcInitialAmount + ((calcInitialAmount * (calcInterestRate/100) * calcLoanTenure));
        document.getElementById('simpleResult').innerHTML = simpleFinalTotal.toFixed(2);
        return document.getElementById('simpleResult').innerHTML;
    }

    function calcAnnualCompound(calcInitialAmount,calcInterestRate,calcLoanTenure){
        let annualFinalTotal = 0;
        annualFinalTotal = calcInitialAmount + calcCompoundInterest(calcInitialAmount,calcInterestRate,calcLoanTenure,1);
        document.getElementById('finalAnnualResult').innerHTML = annualFinalTotal.toFixed(2);
        return document.getElementById('finalAnnualResult').innerHTML;
    }

    function calcMonthlyCompound(calcInitialAmount,calcInterestRate,calcLoanTenure){
        let monthFinalTotal = 0;
        monthFinalTotal = calcInitialAmount + calcCompoundInterest(calcInitialAmount,calcInterestRate,calcLoanTenure,12);
        document.getElementById('finalMonthlyResult').innerHTML = monthFinalTotal.toFixed(2);
        return document.getElementById('finalMonthlyResult').innerHTML;            
    }

    function calcDailyCompound(calcInitialAmount,calcInterestRate,calcLoanTenure){
        let dailyFinalTotal = 0;
        dailyFinalTotal = calcInitialAmount + calcCompoundInterest(calcInitialAmount,calcInterestRate,calcLoanTenure,365);
        document.getElementById('finalDailyResult').innerHTML = dailyFinalTotal.toFixed(2);
        return document.getElementById('finalDailyResult').innerHTML;             
    }

    function calcCompoundInterest(calcInitialAmount,calcInterestRate,calcLoanTenure,compPerYear){
        compInterestTotal = calcInitialAmount*(((1+((calcInterestRate/100)/compPerYear))**(calcLoanTenure*compPerYear))-1);
        return compInterestTotal;
    }
}

}

Variable capture and return to the screen is below:

 <form id="initialValues"> <label for="initialAmount" style="margin-left: 50px"><b>Initial loan or investment amount</b></label><br> <input type="number" id="initialAmount" name="initialAmount" style="margin-left: 50px" value="0"><br> <label for="interestRate" style="margin-left: 50px"><b>Interest rate</b></label><br> <input type="number" id="interestRate" name="interestRate" style="margin-left: 50px" value="0"><br> <label for="loanTenure" style="margin-left: 50px"><b>Loan tenure</b></label><br> <input type="number" id="loanTenure" name="loanTenure" style="margin-left: 50px" value="0"><br> <br> <input type="button" style="margin-left: 50px" value="Submit" onclick="runCalculations.calculateFinalValues()"> <input type="reset" style="margin-left: 50px" value="Reset Values"> </form> <h2>Simple Interest Calculation</h2> <p>Final amount based on simple interest where interest is added in a single amount:</p> <p type="number" id="simpleResult" style="margin-left: 50px; font-weight: bold"></p> <h2>Compound Interest</h2> <p>Final amount where interest is compounded annually:</p> <p id="finalAnnualResult" style="margin-left: 50px; font-weight: bold"><b></b></p> <p>Final amount where interest is compounded monthly:</p> <p id="finalMonthlyResult" style="margin-left: 50px; font-weight: bold"><b></b></p> <p>Final amount where interest is compounded daily:</p> <p id="finalDailyResult" style="margin-left: 50px; font-weight: bold"><b></b></p>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM