Lab 04: Async Validator
π Resourcesβ
π Starter Codeβ
step-3-album-wholesale-v16-post-add-album-form-array
Continue from your Lab 03 result. If you need a fresh copy, use step-3-album-wholesale-v16-post-add-album-form-array as your base and complete Lab 03 first.
In this lab, you'll build an asynchronous validator that checks if an album already exists by making HTTP requests. You'll use RxJS operators like debounceTime and switchMap to optimize the validation, and display loading states during async validation.
π Instructionsβ
Step 1: Create Async Validatorβ
Create an async validator that returns an Observable.
The
AlbumServiceexposesisArtistExist(name)andisAlbumExist(artist, name). Use whichever matches your form. This example validates the artist field:
import { AbstractControl, AsyncValidatorFn } from '@angular/forms';
import { of } from 'rxjs';
import { map, debounceTime, switchMap } from 'rxjs/operators';
import { AlbumService } from '../services/album.service';
export function artistExistsValidator(albumService: AlbumService): AsyncValidatorFn {
return (control: AbstractControl) => {
if (!control.value) return of(null);
return of(null).pipe(
debounceTime(300),
switchMap(() => albumService.isArtistExist(control.value)),
map(exists => exists ? { artistExists: true } : null)
);
};
}
Step 2: Apply to FormControlβ
Add async validator as third parameter:
albumForm = this.fb.group({
artist: ['', [Validators.required], [artistExistsValidator(this.albumService)]]
});
Step 3: Show Pending Stateβ
Display loading indicator:
<span *ngIf="albumForm.get('name')?.pending">
Checking...
</span>
<mat-error *ngIf="albumForm.get('artist')?.errors?.['artistExists']">
Artist already exists
</mat-error>