From 249cf0cdd9ee4000327b9981650a91511497a75a Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sun, 8 Mar 2026 00:02:42 +0700 Subject: [PATCH] Bugfix/projected total amount in FIRE calculator (#6490) * Fix projected total amount * Update changelog --- CHANGELOG.md | 4 ++++ .../fire-calculator.component.ts | 23 +++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a837052a..c002057ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Reused the value component in the tag management of the admin control panel - Upgraded `jsonpath` from version `1.1.1` to `1.2.1` +### Fixed + +- Fixed an issue in the _FIRE_ calculator to correctly calculate the projected total amount + ## 2.247.0 - 2026-03-04 ### Changed diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts index 8b472fc47..7a62564c6 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -16,8 +16,8 @@ import { Input, OnChanges, OnDestroy, - ViewChild, - output + output, + viewChild } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { @@ -55,7 +55,7 @@ import { startOfMonth, sub } from 'date-fns'; -import { isNil, isNumber } from 'lodash'; +import { isNumber } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { debounceTime } from 'rxjs'; @@ -90,8 +90,6 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { @Input() retirementDate: Date; @Input() savingsRate = 0; - @ViewChild('chartCanvas') chartCanvas: ElementRef; - public calculatorForm = this.formBuilder.group({ annualInterestRate: new FormControl(null), paymentPerPeriod: new FormControl(null), @@ -99,23 +97,30 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { projectedTotalAmount: new FormControl(null), retirementDate: new FormControl(null) }); + public chart: Chart<'bar'>; public isLoading = true; public minDate = addDays(new Date(), 1); public periodsToRetire = 0; protected readonly annualInterestRateChanged = output(); + protected readonly calculationCompleted = output(); + protected readonly projectedTotalAmountChanged = output(); protected readonly retirementDateChanged = output(); protected readonly savingsRateChanged = output(); private readonly CONTRIBUTION_PERIOD = 12; + private readonly DEFAULT_RETIREMENT_DATE = startOfMonth( addYears(new Date(), 10) ); + private readonly chartCanvas = + viewChild.required>('chartCanvas'); + public constructor( private changeDetectorRef: ChangeDetectorRef, private fireCalculatorService: FireCalculatorService, @@ -272,7 +277,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { const chartData = this.getChartData(); - if (this.chartCanvas) { + if (this.chartCanvas()) { if (this.chart) { this.chart.data.labels = chartData.labels; @@ -282,7 +287,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { this.chart.update(); } else { - this.chart = new Chart<'bar'>(this.chartCanvas.nativeElement, { + this.chart = new Chart<'bar'>(this.chartCanvas().nativeElement, { data: chartData, options: { plugins: { @@ -303,7 +308,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { }).format(totalAmount)}`; }, label: (context) => { - let label = context.dataset.label || ''; + let label = context.dataset.label ?? ''; if (label) { label += ': '; @@ -473,7 +478,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { 'projectedTotalAmount' )?.value; - if (!isNil(projectedTotalAmount)) { + if (projectedTotalAmount) { return projectedTotalAmount; }