Lab 04: Async Validator
📖 Resources
Section titled “📖 Resources”🚀 Starter Code
Section titled “🚀 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
Section titled “📝 Instructions”Step 1: Create Async Validator
Section titled “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
Section titled “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
Section titled “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>
