Skip to main content
The FormControl class tracks the value and validation status of an individual form control. It is one of the four fundamental building blocks of Angular forms, along with FormGroup, FormArray, and FormRecord.

Import

import { FormControl } from '@angular/forms';

Constructor

formState
T | FormControlState<T>
default:"null"
Initial value for the control, or an object that defines the initial value and disabled state.
validatorOrOpts
ValidatorFn | ValidatorFn[] | FormControlOptions | null
A synchronous validator function, an array of such functions, or a FormControlOptions object that contains validation functions and a validation trigger.
asyncValidator
AsyncValidatorFn | AsyncValidatorFn[] | null
A single async validator or array of async validator functions.

Basic Usage

Creating a FormControl

import { FormControl, Validators } from '@angular/forms';

// Simple control with initial value
const nameControl = new FormControl('John');

// Control with validator
const emailControl = new FormControl('', Validators.required);

// Control with initial value and disabled state
const ageControl = new FormControl({ value: 25, disabled: true });

// Control with multiple validators
const passwordControl = new FormControl('', [
  Validators.required,
  Validators.minLength(8)
]);

Type Safety

FormControl accepts a generic type argument:
const ageControl = new FormControl<number>(25);
const nameControl = new FormControl<string>('');

// For nullable values
const optionalControl = new FormControl<string | null>(null);

Properties

value
T
The current value of the control.
status
'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'
The validation status of the control.
valid
boolean
A control is valid when its status is VALID.
invalid
boolean
A control is invalid when its status is INVALID.
pending
boolean
A control is pending when its status is PENDING.
disabled
boolean
A control is disabled when its status is DISABLED.
enabled
boolean
A control is enabled as long as its status is not DISABLED.
errors
ValidationErrors | null
An object containing any errors generated by failing validation, or null if there are no errors.
pristine
boolean
A control is pristine if the user has not yet changed the value in the UI.
dirty
boolean
A control is dirty if the user has changed the value in the UI.
touched
boolean
True if the control is marked as touched.
untouched
boolean
True if the control has not been marked as touched.
defaultValue
T
The default value of this FormControl, used whenever the control is reset without an explicit value.
valueChanges
Observable<T>
A multicasting observable that emits an event every time the value of the control changes.
statusChanges
Observable<FormControlStatus>
A multicasting observable that emits an event every time the validation status of the control recalculates.

Methods

setValue()

Sets a new value for the form control.
value
T
required
The new value for the control.
options.onlySelf
boolean
default:"false"
When true, each change only affects this control, and not its parent.
options.emitEvent
boolean
default:"true"
When true, both the statusChanges and valueChanges observables emit events with the latest status and value.
options.emitModelToViewChange
boolean
default:"true"
When true, each change triggers an onChange event to update the view.
options.emitViewToModelChange
boolean
default:"true"
When true, each change triggers an ngModelChange event to update the model.
const control = new FormControl('initial');
control.setValue('updated');
console.log(control.value); // 'updated'

// Set value without emitting events
control.setValue('silent', { emitEvent: false });

patchValue()

Patches the value of the control. For FormControl, this is functionally the same as setValue().
control.patchValue('new value');

reset()

Resets the form control, marking it pristine and untouched, and resetting the value.
formState
T | FormControlState<T>
Resets the control with an initial value, or an object that defines the initial value and disabled state. If not provided, resets to null or the default value if nonNullable was set.
options.onlySelf
boolean
default:"false"
When true, each change only affects this control, and not its parent.
options.emitEvent
boolean
default:"true"
When true, both the statusChanges and valueChanges observables emit events.
const control = new FormControl('Nancy');
control.reset('Drew');
console.log(control.value); // 'Drew'

// Reset to null (default behavior)
control.reset();
console.log(control.value); // null

// Reset with nonNullable option
const nonNullControl = new FormControl('Nancy', { nonNullable: true });
nonNullControl.reset();
console.log(nonNullControl.value); // 'Nancy'

getRawValue()

Returns the value of the control. For FormControl, the raw value is equivalent to the value.
const value = control.getRawValue();

disable()

Disables the control, meaning it will be exempt from validation checks and excluded from aggregate values of parent controls.
options.onlySelf
boolean
default:"false"
When true, mark only this control. When false, marks all direct ancestors.
options.emitEvent
boolean
default:"true"
When true, emit a statusChanges event.
control.disable();
console.log(control.status); // 'DISABLED'

enable()

Enables the control.
control.enable();
console.log(control.disabled); // false

markAsTouched()

Marks the control as touched.
control.markAsTouched();
console.log(control.touched); // true

markAsUntouched()

Marks the control as untouched.
control.markAsUntouched();
console.log(control.untouched); // true

markAsDirty()

Marks the control as dirty.
control.markAsDirty();
console.log(control.dirty); // true

markAsPristine()

Marks the control as pristine.
control.markAsPristine();
console.log(control.pristine); // true

updateValueAndValidity()

Recalculates the value and validation status of the control.
control.updateValueAndValidity();

setValidators()

Sets the synchronous validators that are active on this control.
validators
ValidatorFn | ValidatorFn[] | null
required
The new validator or validators.
control.setValidators([Validators.required, Validators.minLength(5)]);
control.updateValueAndValidity();

setAsyncValidators()

Sets the asynchronous validators that are active on this control.
control.setAsyncValidators(asyncValidator);
control.updateValueAndValidity();

addValidators()

Adds validators to the control.
control.addValidators(Validators.email);
control.updateValueAndValidity();

removeValidators()

Removes validators from the control.
control.removeValidators(Validators.required);
control.updateValueAndValidity();

hasError()

Reports whether the control has the error specified.
errorCode
string
required
The error code to check for.
path
string | (string | number)[]
Path to check (used in FormGroup/FormArray).
const control = new FormControl('', Validators.required);
console.log(control.hasError('required')); // true

getError()

Retrieves the error object for the specified error code.
const control = new FormControl(2, Validators.min(3));
console.log(control.getError('min')); // { min: 3, actual: 2 }

FormControlOptions

Options object for configuring a FormControl.
validators
ValidatorFn | ValidatorFn[]
A synchronous validator function, or an array of such functions.
asyncValidators
AsyncValidatorFn | AsyncValidatorFn[]
A single async validator or array of async validator functions.
updateOn
'change' | 'blur' | 'submit'
default:"'change'"
The event on which the control should update its value and validity.
nonNullable
boolean
default:"false"
Whether to use the initial value as the default value. When true, the control will reset to its initial value instead of null.
const control = new FormControl('value', {
  validators: Validators.required,
  asyncValidators: asyncValidator,
  updateOn: 'blur',
  nonNullable: true
});

FormControlState

Interface for defining both a value and disabled state for a FormControl.
value
T
required
The value of the control.
disabled
boolean
required
Whether the control is disabled.
const control = new FormControl({ value: 'text', disabled: true });
console.log(control.value); // 'text'
console.log(control.disabled); // true

Examples

Non-Nullable FormControl

const control = new FormControl('Nancy', { nonNullable: true });

console.log(control.value); // 'Nancy'

control.reset();
console.log(control.value); // 'Nancy' (not null)

Update on Blur

const control = new FormControl('', {
  validators: Validators.required,
  updateOn: 'blur'
});

// Value and validation only update when the control loses focus

Listening to Value Changes

const control = new FormControl('');

control.valueChanges.subscribe(value => {
  console.log('Value changed to:', value);
});

control.setValue('new value'); // Logs: 'Value changed to: new value'

Custom Async Validator

import { AbstractControl, ValidationErrors } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { delay, map } from 'rxjs/operators';

function usernameValidator(control: AbstractControl): Observable<ValidationErrors | null> {
  return checkUsernameAvailability(control.value).pipe(
    map(available => available ? null : { usernameTaken: true })
  );
}

const usernameControl = new FormControl('', {
  validators: Validators.required,
  asyncValidators: usernameValidator
});

console.log(usernameControl.status); // 'PENDING' during validation

See Also

Build docs developers (and LLMs) love