Description
Which @angular/* package(s) are relevant/related to the feature request?
forms
Description
Currently, there is no way to listen to just the raw value changes of a reactive form, only the value changes. This means that every time the status of the form changes (i.e. disabled/enabled), a new value is emitted even though the raw value itself hasn't changed. Ideally, there would be a simple way to listen for just raw value changes so that you could use the raw value for output emissions.
Proposed solution
Add a rawValueChanges
method.
protected readonly formModified = output<{ firstName: string | null; lastName: string | null }>();
protected readonly form = new FormGroup({
firstName: new FormControl('John'),
lastName: new FormControl('Doe')
});
constructor() {
this.form.rawValueChanges
.pipe(takeUntilDestroyed())
.subscribe(rawValue => this.formModified.emit(rawValue));
}
This would allow a user to still enable/disable the form without emitting the same value twice.
Alternatives considered
Using a custom distinctUntilChanged
pipe to handle values.
protected readonly formModified = output<{ firstName: string | null; lastName: string | null }>();
protected readonly form = new FormGroup({
firstName: new FormControl('John'),
lastName: new FormControl('Doe')
});
constructor() {
this.form.valueChanges
.pipe(
takeUntilDestroyed(),
startWith(this.form.getRawValue()),
map(() => this.form.getRawValue()),
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),
skip(1)
)
.subscribe(rawValue => this.formModified.emit(rawValue));
}
This isn't ideal: it requires the use of JSON.stringify to ensure deeper comparison (allowing FormGroup or FormArray comparison to work). It's also a lot of logic that could be easily avoided by simply having a separate observable to watch the raw value.