useFormPending
Returns whether a FormGroup has pending async validators as a signal. The signal updates reactively whenever the form's pending state changes.
Usage
typescript
import { useFormPending } from 'ng-reactive-utils';
@Component({
template: `
<form [formGroup]="form">
<input formControlName="username" placeholder="Username" />
@if (isPending()) {
<span class="loading">Checking availability...</span>
}
<button [disabled]="isPending()">
@if (isPending()) {
Validating...
} @else {
Submit
}
</button>
</form>
`,
})
class RegistrationComponent {
form = new FormGroup({
username: new FormControl('', [], [this.usernameValidator()]),
});
isPending = useFormPending(this.form);
usernameValidator(): AsyncValidatorFn {
return (control) => {
return this.userService
.checkUsername(control.value)
.pipe(map((exists) => (exists ? { usernameTaken: true } : null)));
};
}
}Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
form | FormGroup | required | The FormGroup to check pending state for |
Returns
Signal<boolean> - A readonly signal containing the pending state (true if async validators are running)
Notes
- Uses
toSignalwithform.statusChangesobservable - Returns
truewhen any control has running async validators - Returns
falsewhen all async validators have completed - Useful for showing loading indicators during async validation
Source
ts
import { Signal } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { FormGroup } from '@angular/forms';
import { map } from 'rxjs';
/**
* Returns whether a FormGroup has pending async validators as a signal.
* The signal updates reactively whenever the form's pending state changes.
*
* @param form - The FormGroup to check pending state for
* @returns A signal containing the pending state (true if async validators are running)
*
* @example
* ```typescript
* @Component({
* template: `
* <form [formGroup]="form">
* <input formControlName="username" />
* @if (isPending()) {
* <span>Checking availability...</span>
* }
* </form>
* `
* })
* class MyComponent {
* form = new FormGroup({
* username: new FormControl('', [], [asyncUsernameValidator])
* });
* isPending = useFormPending(this.form);
* }
* ```
*/
export const useFormPending = (form: FormGroup): Signal<boolean> => {
return toSignal(form.statusChanges.pipe(map(() => form.pending)), {
initialValue: form.pending,
}) as Signal<boolean>;
};