Skip to content

useFormStatus

Returns the validation status of a FormGroup as a signal. The signal updates reactively whenever the form's status changes.

Usage

typescript
import { useFormStatus } from 'ng-reactive-utils';

@Component({
  template: `
    <form [formGroup]="form">
      <input formControlName="email" />

      <div [class]="'status-' + formStatus().toLowerCase()">Status: {{ formStatus() }}</div>

      @switch (formStatus()) {
        @case ('VALID') {
          <button type="submit">Submit</button>
        }
        @case ('INVALID') {
          <p class="error">Please fix the errors above</p>
        }
        @case ('PENDING') {
          <p class="loading">Validating...</p>
        }
        @case ('DISABLED') {
          <p class="info">Form is disabled</p>
        }
      }
    </form>
  `,
  styles: `
    .status-valid {
      color: green;
    }
    .status-invalid {
      color: red;
    }
    .status-pending {
      color: orange;
    }
    .status-disabled {
      color: gray;
    }
  `,
})
class StatusFormComponent {
  form = new FormGroup({
    email: new FormControl('', [Validators.required, Validators.email]),
  });

  formStatus = useFormStatus(this.form);
}

Parameters

ParameterTypeDefaultDescription
formFormGrouprequiredThe FormGroup to get status from

Returns

Signal<FormControlStatus> - A readonly signal containing the form status

Status Values

StatusDescription
VALIDAll controls pass validation
INVALIDAt least one control has validation errors
PENDINGAt least one control has pending async validators
DISABLEDThe form is disabled

Notes

  • Uses toSignal with form.statusChanges observable
  • Status is determined by the combined status of all controls
  • Useful for conditional rendering based on form state

Source

ts
import { Signal } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { FormGroup, FormControlStatus } from '@angular/forms';

/**
 * Returns the validation status of a FormGroup as a signal.
 * The signal updates reactively whenever the form's status changes.
 *
 * Status values:
 * - 'VALID': All controls are valid
 * - 'INVALID': At least one control is invalid
 * - 'PENDING': At least one control has pending async validators
 * - 'DISABLED': The form is disabled
 *
 * @param form - The FormGroup to get status from
 * @returns A signal containing the form status
 *
 * @example
 * ```typescript
 * @Component({
 *   template: `
 *     <form [formGroup]="form">
 *       <input formControlName="email" />
 *       <span>Status: {{ formStatus() }}</span>
 *     </form>
 *   `
 * })
 * class MyComponent {
 *   form = new FormGroup({
 *     email: new FormControl('', Validators.required)
 *   });
 *   formStatus = useFormStatus(this.form);
 * }
 * ```
 */
export const useFormStatus = (form: FormGroup): Signal<FormControlStatus> => {
  return toSignal(form.statusChanges, {
    initialValue: form.status,
  }) as Signal<FormControlStatus>;
};

Released under the MIT License.