[](https://www.npmjs.com/package/form-control-change-tracker) [](https://www.npmjs.com/package/form-



!Angular

Try it on StackBlitz - Interactive demo with reactive and template-driven forms (Angular 19)
| Angular Version | Library Version | Status |
| :-------------- | :-------------- | :---------------- |
| v19+ | ^1.0.0 | 🟢 Stable |
| v15 - v19 | 0.0.4 | 🟡 Legacy Support |
The library uses a SimpleStrategy by default, which performs a fast reference check for primitives and a key-order independent deep comparison for objects. To use a different strategy (e.g., deep-diff):
1. Install deep-diff (or your preferred library):
``bash`
npm install deep-diff
npm install @types/deep-diff --save-dev
2. Create the Strategy:
`typescript
import { Injectable } from "@angular/core";
import { ComparisonStrategy } from "form-control-change-tracker";
import { diff } from "deep-diff";
@Injectable()
export class DeepDiffStrategy implements ComparisonStrategy {
isEqual(a: any, b: any): boolean {
// Returns true if no differences found
return !diff(a, b);
}
}
`
3. Provide it in your Module:
`typescript
import { HG_COMPARISON_STRATEGY } from "form-control-change-tracker";
import { DeepDiffStrategy } from "./strategies/deep-diff-strategy";
@NgModule({
// ...
providers: [
{
provide: HG_COMPARISON_STRATEGY,
useClass: DeepDiffStrategy,
},
],
})
export class AppModule {}
`
Very often when developers need to know if there were any changes inside the a form in order to present a unsaved changes confirmation dialog when navigating away or in order to disable the save button when there is nothing new to save. The FormControlChangeTrackerModule provides two things:
- The ChangeTrackerDirective (hgChangeTracker) that can be set on the individual form controls in order to track if any changes are made
- And the @hasChanges() decorator that is applied over the ChangeTrackerDirective directives in order to provide you a boolean value indicating if there are any changes or not.
The new API allows you to track changes directly in your template without needing complex decorators.
Angular 19+ (Standalone Components)
`typescript
import { Component } from "@angular/core";
import { ReactiveFormsModule, FormBuilder, FormGroup } from "@angular/forms";
import { FormControlChangeTrackerModule } from "form-control-change-tracker";
@Component({
selector: "app-my-form",
standalone: true,
imports: [ReactiveFormsModule, FormControlChangeTrackerModule],
template:
,
})
export class MyFormComponent {
form: FormGroup; constructor(private fb: FormBuilder) {
this.form = this.fb.group({
firstName: [""],
lastName: [""],
});
}
submit() {
console.log("Form submitted:", this.form.value);
}
}
`Legacy NgModule (Angular 15-18)
`typescript
// app.module.ts
imports: [
// ...
FormControlChangeTrackerModule,
];
`template
`html
`$3
Debounce Time
Adjust the debounce time for change detection (default: 20ms).
`html
`Multi-Initial Values
Allow multiple values to be considered "valid" (unchanged).
`html
`Auto-Sync
Control whether the directive automatically captures the initial value.
`html
`$3
The library serves backward compatibility for the
@hasChanges() decorator usage.`typescript
@Component({...})
export class MyComponent {
@ViewChildren(ChangeTrackerDirective) @hasChanges() hasFormChanges: boolean;
}
``- Deep Comparison: Uses deep-diff strategies to correctly track object changes.
- Reactive: Built on RxJS for efficient change detection.
- Debounced: Prevents UI thrashing on high-frequency inputs.
- Container Support: Easily aggregate change status for an entire form.