Skip to content

New rawValueChanges Observable for ReactiveFormsModule #61845

@pcbowers

Description

@pcbowers

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions