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 7461f6729..8e5943395 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -55,7 +55,7 @@ import { startOfMonth, sub } from 'date-fns'; -import { isNumber } from 'lodash'; +import { isNil, isNumber } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { Subject, debounceTime, takeUntil } from 'rxjs'; @@ -100,11 +100,11 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { @ViewChild('chartCanvas') chartCanvas: ElementRef; public calculatorForm = this.formBuilder.group({ - annualInterestRate: new FormControl(undefined), - paymentPerPeriod: new FormControl(undefined), - principalInvestmentAmount: new FormControl(undefined), - projectedTotalAmount: new FormControl(undefined), - retirementDate: new FormControl(undefined) + annualInterestRate: new FormControl(null), + paymentPerPeriod: new FormControl(null), + principalInvestmentAmount: new FormControl(null), + projectedTotalAmount: new FormControl(null), + retirementDate: new FormControl(null) }); public chart: Chart<'bar'>; public isLoading = true; @@ -142,35 +142,45 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { const { projectedTotalAmount, retirementDate } = this.calculatorForm.getRawValue(); - this.calculationCompleted.emit({ - projectedTotalAmount, - retirementDate - }); + if (projectedTotalAmount !== null && retirementDate !== null) { + this.calculationCompleted.emit({ + projectedTotalAmount, + retirementDate + }); + } }); this.calculatorForm .get('annualInterestRate') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) .subscribe((annualInterestRate) => { - this.annualInterestRateChanged.emit(annualInterestRate); + if (annualInterestRate !== null) { + this.annualInterestRateChanged.emit(annualInterestRate); + } }); this.calculatorForm .get('paymentPerPeriod') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) .subscribe((savingsRate) => { - this.savingsRateChanged.emit(savingsRate); + if (savingsRate !== null) { + this.savingsRateChanged.emit(savingsRate); + } }); this.calculatorForm .get('projectedTotalAmount') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) .subscribe((projectedTotalAmount) => { - this.projectedTotalAmountChanged.emit(projectedTotalAmount); + if (projectedTotalAmount !== null) { + this.projectedTotalAmountChanged.emit(projectedTotalAmount); + } }); this.calculatorForm .get('retirementDate') - .valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) + ?.valueChanges.pipe(debounceTime(500), takeUntil(this.unsubscribeSubject)) .subscribe((retirementDate) => { - this.retirementDateChanged.emit(retirementDate); + if (retirementDate !== null) { + this.retirementDateChanged.emit(retirementDate); + } }); } @@ -196,11 +206,11 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { this.calculatorForm.patchValue( { annualInterestRate: - this.calculatorForm.get('annualInterestRate').value, + this.calculatorForm.get('annualInterestRate')?.value, paymentPerPeriod: this.getPMT(), principalInvestmentAmount: this.calculatorForm.get( 'principalInvestmentAmount' - ).value, + )?.value, projectedTotalAmount: Math.round(this.getProjectedTotalAmount()) || 0, retirementDate: @@ -210,7 +220,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { emitEvent: false } ); - this.calculatorForm.get('principalInvestmentAmount').disable(); + this.calculatorForm.get('principalInvestmentAmount')?.disable(); this.changeDetectorRef.markForCheck(); }); @@ -219,34 +229,38 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { if (this.hasPermissionToUpdateUserSettings === true) { this.calculatorForm .get('annualInterestRate') - .enable({ emitEvent: false }); - this.calculatorForm.get('paymentPerPeriod').enable({ emitEvent: false }); + ?.enable({ emitEvent: false }); + this.calculatorForm.get('paymentPerPeriod')?.enable({ emitEvent: false }); this.calculatorForm .get('projectedTotalAmount') - .enable({ emitEvent: false }); + ?.enable({ emitEvent: false }); } else { this.calculatorForm .get('annualInterestRate') - .disable({ emitEvent: false }); - this.calculatorForm.get('paymentPerPeriod').disable({ emitEvent: false }); + ?.disable({ emitEvent: false }); + this.calculatorForm + .get('paymentPerPeriod') + ?.disable({ emitEvent: false }); this.calculatorForm .get('projectedTotalAmount') - .disable({ emitEvent: false }); + ?.disable({ emitEvent: false }); } - this.calculatorForm.get('retirementDate').disable({ emitEvent: false }); + this.calculatorForm.get('retirementDate')?.disable({ emitEvent: false }); } public setMonthAndYear( normalizedMonthAndYear: Date, datepicker: MatDatepicker ) { - const retirementDate = this.calculatorForm.get('retirementDate').value; + const retirementDate = + this.calculatorForm.get('retirementDate')?.value ?? + this.DEFAULT_RETIREMENT_DATE; const newRetirementDate = setMonth( setYear(retirementDate, normalizedMonthAndYear.getFullYear()), normalizedMonthAndYear.getMonth() ); - this.calculatorForm.get('retirementDate').setValue(newRetirementDate); + this.calculatorForm.get('retirementDate')?.setValue(newRetirementDate); datepicker.close(); } @@ -426,12 +440,16 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { } private getPeriodsToRetire(): number { - if (this.calculatorForm.get('projectedTotalAmount').value) { + const projectedTotalAmount = this.calculatorForm.get( + 'projectedTotalAmount' + )?.value; + + if (projectedTotalAmount) { let periods = this.fireCalculatorService.calculatePeriodsToRetire({ P: this.getP(), PMT: this.getPMT(), r: this.getR(), - totalAmount: this.calculatorForm.get('projectedTotalAmount').value + totalAmount: projectedTotalAmount }); if (periods === Infinity) { @@ -453,12 +471,15 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { } private getPMT() { - return this.calculatorForm.get('paymentPerPeriod').value; + return this.calculatorForm.get('paymentPerPeriod')?.value ?? 0; } private getProjectedTotalAmount() { - if (this.calculatorForm.get('projectedTotalAmount').value) { - return this.calculatorForm.get('projectedTotalAmount').value; + const projectedTotalAmount = this.calculatorForm.get( + 'projectedTotalAmount' + )?.value; + if (!isNil(projectedTotalAmount)) { + return projectedTotalAmount; } const { totalAmount } = @@ -473,12 +494,12 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { } private getR() { - return this.calculatorForm.get('annualInterestRate').value / 100; + return (this.calculatorForm.get('annualInterestRate')?.value ?? 0) / 100; } private getRetirementDate(): Date { if (this.periodsToRetire === Number.MAX_SAFE_INTEGER) { - return undefined; + return this.DEFAULT_RETIREMENT_DATE; } const monthsToRetire = this.periodsToRetire % 12;