JavaScript Version of Loan Amortization
1. Loan Calculator Function (Pure JS/TS)
export function calculateLoanSchedule(
principal: number,
annualRate: number,
years: number,
extraPayment: number = 0
) {
const monthlyRate = annualRate / 12 / 100;
const months = years * 12;
const monthlyPayment =
(principal * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -months));
const schedule = [];
let balance = principal;
let totalInterest = 0;
let month = 1;
while (balance > 0 && month <= months) {
const interest = balance * monthlyRate;
let principalPayment = monthlyPayment - interest + extraPayment;
if (principalPayment > balance) {
principalPayment = balance;
}
balance -= principalPayment;
totalInterest += interest;
schedule.push({
month,
payment: parseFloat((monthlyPayment + extraPayment).toFixed(2)),
principal: parseFloat(principalPayment.toFixed(2)),
interest: parseFloat(interest.toFixed(2)),
balance: parseFloat(balance.toFixed(2))
});
month++;
}
const totalPaid = schedule.reduce((sum, p) => sum + p.payment, 0);
return {
schedule,
totalPaid: parseFloat(totalPaid.toFixed(2)),
totalInterest: parseFloat(totalInterest.toFixed(2)),
totalMonths: schedule.length
};
}
2. Example Usage in Angular Component
import { Component, OnInit } from '@angular/core';
import { calculateLoanSchedule } from './loan-calculator';
@Component({
selector: 'app-loan-schedule',
templateUrl: './loan-schedule.component.html',
})
export class LoanScheduleComponent implements OnInit {
loanData: any;
schedule: any[] = [];
ngOnInit(): void {
const principal = 300000;
const annualRate = 6.0;
const years = 30;
const extraPayment = 200;
this.loanData = calculateLoanSchedule(principal, annualRate, years, extraPayment);
this.schedule = this.loanData.schedule;
console.log('Loan Summary:', this.loanData);
}
}
3. Optional Template Snippet
<table>
<thead>
<tr>
<th>Month</th>
<th>Payment</th>
<th>Principal</th>
<th>Interest</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of schedule">
<td>{{ row.month }}</td>
<td>{{ row.payment | currency }}</td>
<td>{{ row.principal | currency }}</td>
<td>{{ row.interest | currency }}</td>
<td>{{ row.balance | currency }}</td>
</tr>
</tbody>
</table>
1. Create the Service
Run this command to generate a service:
ng generate service services/loan-calculator
Or manually create:
src/app/services/loan-calculator.service.ts
import { Injectable } from '@angular/core';
export interface LoanScheduleEntry {
month: number;
payment: number;
principal: number;
interest: number;
balance: number;
}
export interface LoanSummary {
schedule: LoanScheduleEntry[];
totalPaid: number;
totalInterest: number;
totalMonths: number;
payoffYears: number;
payoffMonths: number;
}
@Injectable({
providedIn: 'root',
})
export class LoanCalculatorService {
constructor() {}
calculateLoanSchedule(
principal: number,
annualRate: number,
years: number,
extraPayment: number = 0
): LoanSummary {
const monthlyRate = annualRate / 12 / 100;
const totalMonths = years * 12;
const monthlyPayment =
(principal * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -totalMonths));
const schedule: LoanScheduleEntry[] = [];
let balance = principal;
let totalInterest = 0;
let month = 1;
while (balance > 0 && month <= totalMonths) {
const interest = balance * monthlyRate;
let principalPayment = monthlyPayment - interest + extraPayment;
if (principalPayment > balance) {
principalPayment = balance;
}
balance -= principalPayment;
totalInterest += interest;
schedule.push({
month,
payment: parseFloat((monthlyPayment + extraPayment).toFixed(2)),
principal: parseFloat(principalPayment.toFixed(2)),
interest: parseFloat(interest.toFixed(2)),
balance: parseFloat(balance.toFixed(2)),
});
month++;
}
const totalPaid = schedule.reduce((sum, entry) => sum + entry.payment, 0);
const monthsTaken = schedule.length;
return {
schedule,
totalPaid: parseFloat(totalPaid.toFixed(2)),
totalInterest: parseFloat(totalInterest.toFixed(2)),
totalMonths: monthsTaken,
payoffYears: Math.floor(monthsTaken / 12),
payoffMonths: monthsTaken % 12,
};
}
}
✅ 2. Usage in a Component
src/app/components/loan.component.ts
import { Component, OnInit } from '@angular/core';
import { LoanCalculatorService, LoanSummary } from 'src/app/services/loan-calculator.service';
@Component({
selector: 'app-loan',
templateUrl: './loan.component.html',
})
export class LoanComponent implements OnInit {
loanSummary!: LoanSummary;
constructor(private loanCalculator: LoanCalculatorService) {}
ngOnInit(): void {
const principal = 300000;
const annualRate = 6.0;
const years = 30;
const extraPayment = 200;
this.loanSummary = this.loanCalculator.calculateLoanSchedule(
principal,
annualRate,
years,
extraPayment
);
console.log(this.loanSummary);
}
}
✅ 3. Template Example (loan.component.html
)
<h2>Loan Summary</h2>
<p>Total Paid: {{ loanSummary.totalPaid | currency }}</p>
<p>Total Interest: {{ loanSummary.totalInterest | currency }}</p>
<p>Loan Paid Off In: {{ loanSummary.payoffYears }} years and {{ loanSummary.payoffMonths }} months</p>
<table>
<thead>
<tr>
<th>Month</th>
<th>Payment</th>
<th>Principal</th>
<th>Interest</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of loanSummary.schedule">
<td>{{ row.month }}</td>
<td>{{ row.payment | currency }}</td>
<td>{{ row.principal | currency }}</td>
<td>{{ row.interest | currency }}</td>
<td>{{ row.balance | currency }}</td>
</tr>
</tbody>
</table>
No comments:
Post a Comment