Because
FormControl<T>
is more awesome thanFormControl
!
This is a small library to make Angular Forms more type-safe!
- Type-safe versions of
FormControl
,FormGroup
,FormArray
andControlValueAccessor
- 100% compatible with
@angular/forms
and existing Angular libraries! - Easy to use!
- Additional read-only properties
value$
,valid$
,pristine$
,errors$
,enabled$
and more. - A default implementation for
ControlValueAccessor
- Type-safe validators
Angular Forms are not very type-safe. They accept any type of value. This library makes your code more type-safe. More type-safety means smaller risk for bugs!
npm install ngx-typesafe-forms
yarn add ngx-typesafe-forms
Just import your FormControl
, FormGroup
, FormArray
and ControlValueAccessor
from ngx-typesafe-forms
instead of @angular/forms
and you are done!
import { FormControl, FormGroup } from 'ngx-typesafe-forms';
@Component({ /* ... */ })
class YourComponent {
myControl = new FormControl<string>();
myFormGroup = new FormGroup<Person>({
name: new FormControl(),
birthDate: new FormControl(new Date())
});
changeDate(): void {
this.myControl.setValue(123); // error: this will not compile!
this.myFormGroup.controls.birthDate.setValue('foo'); // error: this will not compile!
this.myControl.setValue('Foo'); // yes, this will!
this.myFormGroup.controls.birthDate.setValue(new Date()); // yes, this will!
}
}
Besides the type-safety, we also provide additional reactive properties.
const myControl = new FormControl<string>('bar');
// subscribe to all values, including the existing value!
myControl.value$.subscribe((value) => {
/* ... */
});
// subscribe to validity changes, including the existing valid state!
myControl.valid$.subscribe((valid) => {
/* ... */
});
The recommended properties are:
value$
errors$
enabled$
pristine$
valid$
status$
validValue$
Additionally, we also provide some of their counterparts:
disabled$
dirty$
invalid$
NOTE: all of these streams also include the current (initial) values.
If you want to assume that form values are always valid, just use FormControl<Foo>
.
However, form values can also be null (if invalid). If you want to use this more strictly, you can use FormControl<Foo | null>
or even FormGroup<Invalidated<Foo>>
(which marks all properties as nullable).
Sometimes, it's not guaranteed that a FormGroup
contains a certain form control,
or that it is actually a FormControl
(it could also be a FormArray
).
For that reason, we introduced new methods to FormGroup
in version 1.3.0
:
FormGroup.getControl(name: string)
- returns aAbstractControl
, throws error if it was not found.FormGroup.getFormControl(name: string)
- returns aFormControl
, throws error if it was not found or not instance ofFormControl
.
The same applies for FormArray.at(index: number)
, which returns a AbstractControl
. For that reason we introduced:
FormArray.controlAt(index: number)
- returns aFormControl
, throws error if it is not an instance ofFormControl
.
Thanks goes to these wonderful people (emoji key):
Dirk Luijk 💻 📖 |
Daan Scheerens 🤔 |
Jur Balledux 🐛 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!