2026 Angular Formlari: Reactive Forms, Dogrulama ve Teknik Mulakat Sorulari
Tipli FormBuilder, ozel dogrulayicilar, asenkron dogrulama ve FormArray ile Angular Reactive Forms konusunda uzmanlasin. Mulakat sorulari ve Signal Forms onizlemesi iceriyor.

Angular Reactive Forms, 2026 yilinda kurumsal form gelistirmenin temel tasini olmaya devam ediyor ve basit giris ekranlarindan karmasik cok adimli sihirbazlara kadar olceklenebilen tip-guvenli, test edilebilir form yonetimi sagliyor. Angular 19'un gelistirilmis API'leri ve gelistirici onizlemesinde bulunan Signal Forms ile hem mevcut standardi hem de gelecekteki degisiklikleri anlamak, gelisitiricilere teknik mulakatlarda rekabet avantaji sagliyor.
Reactive Forms, form yapisinin TypeScript'te tanimlandigi model odakli bir yaklasim kullanir ve dogrulama zamanlami, dinamik alan manipulasyonu ve DOM etkilesimi olmadan kapsamli birim testleri uzerinde tam kontrol saglar.
Reactive Forms Mimarisi
Reactive Forms, degismez bir veri modeli uzerinde calisir. Her degisiklik yeni bir durum nesnesi olusturur ve form davranisini tahmin edilebilir ve hata ayiklanabilir kilar. Temel yapi taslari FormControl, FormGroup ve FormArray olup, bunlar FormBuilder servisi araciligiyla yonetilir.
Form modeli (TypeScript) ile sablon (HTML) arasindaki ayrim, dogrulama mantginin bagimsiz olarak test edilmesine olanak tanir. Bu mimari secim ayni zamanda backend konfigurasyonlarina dayali dinamik form olusturmaya da olanak tanir - kurumsal uygulamalarda yaygin bir gereksinim.
import { Component, inject } from '@angular/core';
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-profile',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<input formControlName="email" placeholder="Email" />
<input formControlName="name" placeholder="Full Name" />
<button type="submit" [disabled]="profileForm.invalid">Save</button>
</form>
`
})
export class UserProfileComponent {
private fb = inject(FormBuilder);
// Typed form with NonNullable configuration
profileForm = this.fb.nonNullable.group({
email: ['', [Validators.required, Validators.email]],
name: ['', [Validators.required, Validators.minLength(2)]]
});
onSubmit() {
// profileForm.getRawValue() returns typed object
const data = this.profileForm.getRawValue();
console.log(data.email, data.name); // Both are string, not string | null
}
}Angular 14'te tanitilan nonNullable form builder konfigurasyonu, form degerlerinden nullable tipleri ortadan kaldirir. Bu, kod tabani genelinde null kontrollerini azaltir ve form yonetimini daha tahmin edilebilir kilar.
Karmasik Is Kurallari icin Ozel Dogrulayicilar
Yerlesik dogrulayicilar yaygin senaryolari kapsarken, gercek dunya uygulamalari ozel dogrulama mantigi gerektirir. Angular hem senkron hem de asenkron dogrulayicilari destekler; asenkron dogrulayicilar kullanici adi kullanilabilirligi gibi sunucu tarafi kontrolleri icin kullanislidir.
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
// Synchronous validator: password strength
export function strongPassword(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const value = control.value;
if (!value) return null;
const hasUpperCase = /[A-Z]/.test(value);
const hasLowerCase = /[a-z]/.test(value);
const hasNumber = /\d/.test(value);
const hasSpecial = /[!@#$%^&*]/.test(value);
const isLongEnough = value.length >= 8;
const valid = hasUpperCase && hasLowerCase && hasNumber && hasSpecial && isLongEnough;
return valid ? null : {
strongPassword: {
hasUpperCase,
hasLowerCase,
hasNumber,
hasSpecial,
isLongEnough
}
};
};
}
// Cross-field validator: password confirmation
export function passwordMatch(): ValidatorFn {
return (group: AbstractControl): ValidationErrors | null => {
const password = group.get('password')?.value;
const confirm = group.get('confirmPassword')?.value;
return password === confirm ? null : { passwordMismatch: true };
};
}Dogrulayicilar tarafindan dondurlen hata nesnesi, hangi belirli kontrollerin basarisiz olduguna dair ayrintili bilgi icerebilir. Bu, genel "gecersiz sifre" geri bildirimi yerine ayrintili hata mesajlari saglar.
@Component({
selector: 'app-registration',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<form [formGroup]="registrationForm" (ngSubmit)="register()">
<input formControlName="password" type="password" />
<input formControlName="confirmPassword" type="password" />
@if (registrationForm.errors?.['passwordMismatch']) {
<span class="error">Passwords do not match</span>
}
</form>
`
})
export class RegistrationComponent {
private fb = inject(FormBuilder);
registrationForm = this.fb.nonNullable.group({
password: ['', [Validators.required, strongPassword()]],
confirmPassword: ['', Validators.required]
}, { validators: passwordMatch() }); // Group-level validator
}Grup seviyesi dogrulayicilar tum FormGroup'u alir ve birden fazla alani kapsayan dogrulama kurallarina olanak tanir. Bu model, alanlar arasi mantik gerektiren her senaryo icin gecerlidir: tarih araliklari, kosullu gereksinimler veya iliskili alan kombinasyonlari.
Asenkron Dogrulayicilar ve Debouncing
Asenkron dogrulayicilar, kullanici arayuzunu engellemeden sunucu tarafi kontrolleri gerceklestirir. Yaygin kullanim ornekleri arasinda benzersiz kullanici adlarini dogrulama, e-posta kullanilabilirligini kontrol etme veya promosyon kodlarini bir API'ye karsi dogrulama yer alir.
import { AbstractControl, AsyncValidatorFn, ValidationErrors } from '@angular/forms';
import { Observable, of, timer } from 'rxjs';
import { map, switchMap, catchError } from 'rxjs/operators';
import { inject } from '@angular/core';
import { UserService } from '../services/user.service';
export function uniqueEmailValidator(userService: UserService): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
if (!control.value) {
return of(null);
}
// Debounce 300ms to avoid excessive API calls
return timer(300).pipe(
switchMap(() => userService.checkEmailAvailable(control.value)),
map(isAvailable => isAvailable ? null : { emailTaken: true }),
catchError(() => of(null)) // Fail open on network errors
);
};
}timer kullanan debounce modeli, her tus vurusunda API isteklerini onler. switchMap operatoru, yeni giris geldiginde bekleyen istekleri iptal eder ve yalnizca en son degerin sunucu kontrolunu tetiklemesini saglar.
@Component({
selector: 'app-signup',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<form [formGroup]="signupForm">
<input formControlName="email" />
@if (emailControl.pending) {
<span>Checking availability...</span>
}
@if (emailControl.errors?.['emailTaken']) {
<span class="error">This email is already registered</span>
}
</form>
`
})
export class SignupComponent {
private fb = inject(FormBuilder);
private userService = inject(UserService);
signupForm = this.fb.nonNullable.group({
email: ['',
[Validators.required, Validators.email],
[uniqueEmailValidator(this.userService)] // Async validator as 3rd argument
]
});
get emailControl() {
return this.signupForm.controls.email;
}
}Asenkron dogrulayicilar, senkron dogrulayicilar gecildikten sonra calisir ve hatali bicimlendirilmis girisler icin gereksiz API cagrilarindan kacinir. pending durumu devam eden dogrulamayi belirtir ve sablonda yukleme gostergelerini etkinlestirir.
Angular mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
FormArray ile Dinamik Formlar
FormArray, dinamik form kontrol koleksiyonlarina olanak tanir - birden fazla adres, telefon numarasi veya siparis kalemi ekleme gibi senaryolar icin gereklidir. Her dizi elemani basit bir FormControl veya ic ice gecmis bir FormGroup olabilir.
import { Component, inject } from '@angular/core';
import { FormBuilder, FormArray, ReactiveFormsModule, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-order-form',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<form [formGroup]="orderForm">
<div formArrayName="items">
@for (item of itemsArray.controls; track item; let i = $index) {
<div [formGroupName]="i" class="item-row">
<input formControlName="productName" placeholder="Product" />
<input formControlName="quantity" type="number" />
<input formControlName="price" type="number" />
<button type="button" (click)="removeItem(i)">Remove</button>
</div>
}
</div>
<button type="button" (click)="addItem()">Add Item</button>
<p>Total: {{ calculateTotal() | currency }}</p>
</form>
`
})
export class OrderFormComponent {
private fb = inject(FormBuilder);
orderForm = this.fb.group({
items: this.fb.array<FormGroup>([])
});
get itemsArray(): FormArray {
return this.orderForm.get('items') as FormArray;
}
addItem() {
const itemGroup = this.fb.nonNullable.group({
productName: ['', Validators.required],
quantity: [1, [Validators.required, Validators.min(1)]],
price: [0, [Validators.required, Validators.min(0)]]
});
this.itemsArray.push(itemGroup);
}
removeItem(index: number) {
this.itemsArray.removeAt(index);
}
calculateTotal(): number {
return this.itemsArray.controls.reduce((sum, control) => {
const quantity = control.get('quantity')?.value || 0;
const price = control.get('price')?.value || 0;
return sum + (quantity * price);
}, 0);
}
}track ile @for blogu, Angular'in tum listeyi yeniden render etmek yerine yalnizca degisen elemanlari verimli bir sekilde guncellemesini saglar. Buyuk diziler icin bu optimizasyon performansi onemli olcude arttirir.
Signal Forms: Angular Form Yonetiminin Gelecegi
Angular 20, Reactive Forms'a sinyal tabanli bir alternatif sunan Signal Forms'u gelistirici onizlemesinde tanitti. Angular 21.2, geleneksel FormGroups icinde sinyal destekli alanlara izin vererek kademeli geçis icin SignalFormControl wrapper ekledi.
import { Component, signal, computed } from '@angular/core';
import { SignalFormControl } from '@angular/forms';
@Component({
selector: 'app-signal-form',
standalone: true,
template: `
<input [value]="name()" (input)="name.set($any($event.target).value)" />
<p>Character count: {{ charCount() }}</p>
<p>Valid: {{ isValid() }}</p>
`
})
export class SignalFormExampleComponent {
// Signal-based form state
name = signal('');
// Computed values automatically update
charCount = computed(() => this.name().length);
isValid = computed(() => this.name().length >= 3);
}Signal Forms, valueChanges aboneliklerine olan ihtiyaci ortadan kaldirir. Computed sinyaller dogrulama durumunu ve bagimli degerleri otomatik olarak turetir ve Angular'in zoneless degisiklik algilamasiyla entegre olur. Hala gelistirici onizlemesinde olsa da, Signal Forms, Angular'da form yonetiminin gidecegi yonu temsil ediyor.
Temel fark: Reactive Forms durum degisiklikleri icin RxJS Observables kullanirken, Signal Forms Angular Signals kullanir. 2026 sonlari veya sonrasinda baslayan yeni projeler icin, Signal Forms kararli duruma ulastiginda onerilen yaklasim haline gelebilir.
Angular Forms Hakkinda Yaygin Mulakat Sorulari
Teknik mulakatlar siklikla form yonetimi bilgisini test eder. Deneyimli adaylari ayiran modeller sunlardir:
S: Form durumu sifirlamayi form kontrolu sifirlamayla nasil yonetirsiniz?
// Reset entire form to initial values
this.form.reset(); // All controls become null (or default if nonNullable)
// Reset with specific values
this.form.reset({ email: '', name: 'Guest' });
// Reset single control
this.form.controls.email.reset();
// Mark as pristine without changing values
this.form.markAsPristine();
this.form.markAsUntouched();S: setValue ve patchValue arasindaki fark nedir?
// setValue requires ALL controls - throws if missing any
this.form.setValue({ email: 'a@b.com', name: 'Test' }); // Must include both
// patchValue allows partial updates
this.form.patchValue({ email: 'a@b.com' }); // Name unchangedS: Form kontrolunu gonderimde degerini kaybetmeden nasil devre disi birakirsiniz?
this.form.controls.email.disable();
console.log(this.form.value); // { name: 'Test' } - email missing
// Use getRawValue() to include disabled controls
console.log(this.form.getRawValue()); // { email: 'a@b.com', name: 'Test' }Bu nüanslari anlamak pratik deneyimi gosterir. Mulakatcilar genellikle form durum yonetimindeki uc durumlar hakkinda farkindaligi arastirirlar, ozellikle devre disi birakilmis kontroller ve kismi guncellemeler etrafinda.
Angular form ile ilgili mulakat sorularinda daha derin pratik icin, Reactive Forms mulakat sorulari modulu ve Template-Driven Forms modulu incelenebilir.
Uretim Formlari icin En Iyi Uygulamalar
Uretim uygulamalari, temel form olusturmanin otesinde modeller gerektirir. Hata isleme, erisilebilirlik ve performans buyuk olcekte kritik hale gelir.
import { Component, input } from '@angular/core';
import { AbstractControl, ValidationErrors } from '@angular/forms';
@Component({
selector: 'app-form-errors',
standalone: true,
template: `
@if (control().invalid && (control().dirty || control().touched)) {
<div class="errors" role="alert">
@if (control().errors?.['required']) {
<span>This field is required</span>
}
@if (control().errors?.['email']) {
<span>Enter a valid email address</span>
}
@if (control().errors?.['minlength']) {
<span>Minimum {{ control().errors?.['minlength'].requiredLength }} characters</span>
}
</div>
}
`
})
export class FormErrorsComponent {
control = input.required<AbstractControl>();
}role="alert" ozelligi, ekran okuyucularin hata mesajlarini gorundukleri anda duyurmasini saglar. Hem dirty hem de touched kontrolu, kullanici etkilesiminden once hatalarin gosterilmesini onler ve hayal kirikligi yaratan erken dogrulama geri bildiriminden kacinir.
Alanlar arasi dogrulama ve asenkron kontroller dahil kapsamli form dogrulama modelleri icin, Angular RxJS Fundamentals modulu form durum yonetiminin altinda yatan Observable modellerini kapsar.
Sonuc
- Reactive Forms, karmasik kurumsal uygulamalar icin uygun tip-guvenli, test edilebilir form yonetimi saglar
- Ozel dogrulayicilar hem senkron is kurallarini hem de yerlesik debouncing ile asenkron sunucu tarafi kontrollerini destekler
- FormArray,
trackaraciligiyla verimli degisiklik izleme ile dinamik form koleksiyonlarina olanak tanir - Signal Forms (gelistirici onizlemesi), Angular'in zoneless gelecegi ile uyumlu daha basit bir reaktif model sunar
- Uretim formlari erisilebilirlik degerlendirmeleri ve yeniden kullanilabilir hata goruntuleme bilesenleri gerektirir
setValuevspatchValuevegetRawValue()vsvalueanlayisi deneyimli adaylari ayirt eder
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.

Yazan:
Anthony Fillion-MailletFullstack geliştirici, SharpSkill kurucusu
10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.
17 Ağustos 2026 tarihinde güncellendi
Paylaş
İlgili makaleler

NgRx Signal Store vs Klasik NgRx 2026: Hangisini Secmelisiniz?
Angular durum yonetimi icin NgRx Signal Store ve Klasik NgRx kapsamli karsilastirmasi. Pratik kod ornekleri ve 2026 tavsiyeleri.

Angular'da RxJS 2026: Operatörler, Subject'ler ve Signals Interop
Angular'da RxJS 2026: üretimde kullanılan operatörleri, Subject'leri ve Signals interop kalıplarını öğrenin, ayrıca en sık karşılaşılan mülakat sorularını.

Angular @defer 2026: Daha Hızlı Uygulamalar için Bildirimsel Lazy Loading
Angular @defer bloklarında ustalaşın: bildirimsel lazy loading. Tetikleyiciler, prefetching, artımlı hidrasyon, SSR davranışı ve gerçek dünya performans kalıplarına derinlemesine bakış.