WEB-643 fix(clients): add takeUntil pattern to prevent memory leaks in client-general-step component (#3065)

improve
This commit is contained in:
Shubham Kumar
2026-01-31 13:54:14 -06:00
committed by GitHub
parent c1cacdfb6d
commit 163ad131d7
@@ -7,7 +7,7 @@
*/ */
/** Angular Imports */ /** Angular Imports */
import { Component, OnInit, Input, Output, EventEmitter, inject } from '@angular/core'; import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, inject } from '@angular/core';
import { import {
UntypedFormBuilder, UntypedFormBuilder,
UntypedFormGroup, UntypedFormGroup,
@@ -15,6 +15,8 @@ import {
UntypedFormControl, UntypedFormControl,
ReactiveFormsModule ReactiveFormsModule
} from '@angular/forms'; } from '@angular/forms';
import { Subject } from 'rxjs';
import { filter, switchMap, takeUntil } from 'rxjs/operators';
import { ClientsService } from 'app/clients/clients.service'; import { ClientsService } from 'app/clients/clients.service';
import { Dates } from 'app/core/utils/dates'; import { Dates } from 'app/core/utils/dates';
@@ -44,12 +46,15 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
MatStepperNext MatStepperNext
] ]
}) })
export class ClientGeneralStepComponent implements OnInit { export class ClientGeneralStepComponent implements OnInit, OnDestroy {
private formBuilder = inject(UntypedFormBuilder); private formBuilder = inject(UntypedFormBuilder);
private dateUtils = inject(Dates); private dateUtils = inject(Dates);
private settingsService = inject(SettingsService); private settingsService = inject(SettingsService);
private clientService = inject(ClientsService); private clientService = inject(ClientsService);
/** Subject to trigger unsubscription on destroy */
private destroy$ = new Subject<void>();
@Output() legalFormChangeEvent = new EventEmitter<{ legalForm: number }>(); @Output() legalFormChangeEvent = new EventEmitter<{ legalForm: number }>();
/** Minimum date allowed. */ /** Minimum date allowed. */
@@ -151,7 +156,10 @@ export class ClientGeneralStepComponent implements OnInit {
* Adds controls conditionally. * Adds controls conditionally.
*/ */
buildDependencies() { buildDependencies() {
this.createClientForm.get('legalFormId').valueChanges.subscribe((legalFormId: number) => { this.createClientForm
.get('legalFormId')
.valueChanges.pipe(takeUntil(this.destroy$))
.subscribe((legalFormId: number) => {
this.legalFormChangeEvent.emit({ legalForm: legalFormId }); this.legalFormChangeEvent.emit({ legalForm: legalFormId });
if (legalFormId === 1) { if (legalFormId === 1) {
this.createClientForm.removeControl('fullname'); this.createClientForm.removeControl('fullname');
@@ -198,25 +206,41 @@ export class ClientGeneralStepComponent implements OnInit {
} }
}); });
this.createClientForm.get('legalFormId').patchValue(1); this.createClientForm.get('legalFormId').patchValue(1);
this.createClientForm.get('active').valueChanges.subscribe((active: boolean) => { this.createClientForm
.get('active')
.valueChanges.pipe(takeUntil(this.destroy$))
.subscribe((active: boolean) => {
if (active) { if (active) {
this.createClientForm.addControl('activationDate', new UntypedFormControl('', Validators.required)); this.createClientForm.addControl('activationDate', new UntypedFormControl('', Validators.required));
} else { } else {
this.createClientForm.removeControl('activationDate'); this.createClientForm.removeControl('activationDate');
} }
}); });
this.createClientForm.get('addSavings').valueChanges.subscribe((active: boolean) => { this.createClientForm
.get('addSavings')
.valueChanges.pipe(takeUntil(this.destroy$))
.subscribe((active: boolean) => {
if (active) { if (active) {
this.createClientForm.addControl('savingsProductId', new UntypedFormControl('', Validators.required)); this.createClientForm.addControl('savingsProductId', new UntypedFormControl('', Validators.required));
} else { } else {
this.createClientForm.removeControl('savingsProductId'); this.createClientForm.removeControl('savingsProductId');
} }
}); });
this.createClientForm.get('officeId').valueChanges.subscribe((officeId: number) => { this.createClientForm
this.clientService.getClientWithOfficeTemplate(officeId).subscribe((clientTemplate: any) => { .get('officeId')
.valueChanges.pipe(
filter((officeId: number) => !!officeId),
switchMap((officeId: number) => this.clientService.getClientWithOfficeTemplate(officeId)),
takeUntil(this.destroy$)
)
.subscribe((clientTemplate: any) => {
this.staffOptions = clientTemplate.staffOptions; this.staffOptions = clientTemplate.staffOptions;
}); });
}); }
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
} }
getDateLabel(legalFormId: number, values: string[]): string { getDateLabel(legalFormId: number, values: string[]): string {