Angular uygulamalarında veri akışını yönetmek için sıklıkla kullanılan iki önemli kavram vardır: Observable ve BehaviorSubject. Bu kavramlar, uygulamalarımızda gerçek zamanlı güncellemeler, veri paylaşımı ve karmaşık durum yönetimi gibi senaryoları ele almamıza olanak tanır. Bu makalede, Observable ve BehaviorSubject’ın ne olduğunu, aralarındaki farkları ve hangi durumlarda hangisini kullanmanız gerektiğini detaylı bir şekilde inceleyeceğiz.
Observable Nedir?
Observable, zaman içinde birden fazla değer yayımlayan bir nesnedir. Bu değerler, herhangi bir olay (tıklama, veri alımı vb.) veya belirli bir zaman aralığında tetiklenebilir. Observable’lar, veri akışını temsil etmenin güçlü bir yoludur ve genellikle asenkron işlemlerle birlikte kullanılır.
Örnek: Bir HTTP isteği ile sunucudan veri çekmek istediğimizi düşünelim. Bu istek, bir Observable olarak temsil edilebilir. İstek tamamlandığında, Observable bize bir cevap döndürür ve bu cevap, abone olan bileşenler tarafından işlenir.
Aşağıdaki kodda kullanım örneğini görebiliriz.
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
// rxjs kütüphanesinden Observable'ı içe aktarırız. Observable, zaman içerisinde değişebilen değerleri temsil eder.
// Bu sayede, HTTP isteklerinin sonuçlarını yönetebiliriz.
@Injectable({ providedIn: 'root' })
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
// getData metodu, bir Observable döndürür. Bu Observable, HTTP isteğinin sonucunu temsil eder.
return this.http.get('https://api.sam.com/data');
// Bu satır, belirtilen URL'ye bir HTTP GET isteği gönderir.
// İsteğin sonucu, Observable aracılığıyla geri döndürülür.
}
}
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent {
// data değişkeni, sunucudan alınan veriyi tutacak
data: any;
constructor(private dataService: DataService) {}
// Bileşenin constructor'ı, DataService servisini enjekte eder.
ngOnInit() {
// ngOnInit yaşam döngüsü kancası, bileşen ilk kez oluşturulduğunda çağrılır.
this.dataService.getData()
.subscribe(response => {
this.data = response; // Sunucudan gelen veriyi data değişkenine atarız.
});
}
}
BehaviorSubject Nedir?
BehaviorSubject, Observable’ın özel bir türüdür. Diğer Observable’lardan farklı olarak, BehaviorSubject’ın başlangıç değeri vardır ve bu değeri abone olan her gözlemciye hemen gönderir. Ayrıca, yeni bir değer yayımlandığında, bu değer tüm abone olan gözlemcilere iletilir.
Örnek: Bir sayfada kullanıcı adı bilgisini saklamak istediğimizi düşünelim. Bu bilgiyi bir BehaviorSubject içinde tutabilir ve bu şekilde farklı bileşenler arasında paylaşabiliriz.
import { BehaviorSubject } from 'rxjs'; // BehaviorSubject sınıfını rxjs kütüphanesinden içe aktarır
@Injectable({ providedIn: 'root' })
export class AuthService {
private userSubject: BehaviorSubject<string>('');
private userSubject = new BehaviorSubject<string>(''); // Bir BehaviorSubject nesnesi oluşturulur. Bu nesne, kullanıcı adı bilgisini tutar.
public user$ = this.userSubject.asObservable(); // BehaviorSubject'ın observable'ına erişim için bir property tanımlanır.
setUser(username: string) {
this.userSubject.next(username); // Yeni kullanıcı adı, BehaviorSubject'a gönderilir.
}
}
import { Component } from '@angular/core';
import { AuthService } from './auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
// username değişkeni, kullanıcının girdiği kullanıcı adını tutar
username: string = '';
constructor(private authService: AuthService) {}
// Bileşenin constructor'ı, AuthService servisini enjekte eder.
onSubmit() {
// Burada, kullanıcı adı ve şifre doğrulaması gibi işlemler yapılabilir.
// Örneğin, bir HTTP isteği göndererek sunucuya kullanıcı bilgilerini gönderebilirsiniz.
this.authService.setUser(this.username);
// Kullanıcı adı doğrulama işlemlerinden sonra, AuthService'in setUser metodu çağrılır.
// Bu metot, kullanıcı adını AuthService'e iletir ve AuthService bu kullanıcı adını kullanarak oturum açma işlemlerini gerçekleştirir.
}
}
LoginComponent
içerisinde, onSubmit
metodu kullanıcının giriş bilgilerini onaylar ve ardından authService.setUser(username)
methodunu çağırır. Bu method, kullanıcı adını userSubject
isimli BehaviorSubject'a iletir.
Kullanıcı Bilgisini Abone Olma
Başka bir bileşende, userSubject
tarafından yayınlanan değerlere abone olabilirsiniz. Örneğin, bir HeaderComponent
içerisinde oturum açmış kullanıcıyı görüntülemek isteyebilirsiniz:
import { Component, OnInit } from '@angular/core';
import { AuthService } from './auth.service';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
// currentUser değişkeni, oturum açmış kullanıcının adını tutar
currentUser: string = '';
constructor(private authService: AuthService) {}
// Bileşenin constructor'ı, AuthService servisini enjekte eder.
ngOnInit() {
// ngOnInit yaşam döngüsü kancası, bileşen ilk kez oluşturulduğunda çağrılır.
this.authService.user$.subscribe(user => {
this.currentUser = user;
});
}
}
Abonelikten Çıkma
Bellek sızıntılarını önlemek için, bileşen yok edilirken user$
'a abonelikten çıkılması önemlidir. Bunu ngOnDestroy
yaşam döngüsü kancası içerisinde yapabilirsiniz:
ngOnDestroy() {
// Aboneliği iptal edin
this.subscription?.unsubscribe();
}
Observable ve BehaviorSubject Arasındaki Farklar
Hangi Durumda Hangi Kavram Kullanılmalı?
Observable
- HTTP istekleri
- Web Sockets
- Timer’lar
- Event’ler (tıklama, mouse hareketleri vb.)
BehaviorSubject
- Form verileri
- Kullanıcı oturum bilgileri
- Bileşenler arasında veri paylaşımı
- Uygulama durumu
Pratik Örnek: Form Yönetimi
import { Component } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'app-my-form',
templateUrl: './my-form.component.html',
styleUrls: ['./my-form.component.css']
})
export class MyFormComponent {
// private formValueSubject = new BehaviorSubject<string>('');
private formValueSubject = new BehaviorSubject<string>(''); // Bir BehaviorSubject nesnesi oluşturulur. Bu nesne, form değerini tutar.
public formValue$ = this.formValueSubject.asObservable(); // BehaviorSubject'ın observable'ına erişim için bir property tanımlanır.
onFormSubmit(value: string) {
this.formValueSubject.next(value); // Yeni form değeri BehaviorSubject'a gönderilir.
}
}
Bu örnekte, form verileri bir BehaviorSubject ile yönetilmektedir. Formdaki herhangi bir değişiklik, BehaviorSubject’ı günceller ve bu sayede diğer bileşenler de bu değişiklikten haberdar olur.
Observable ve BehaviorSubject, Angular uygulamalarında veri akışını yönetmek için güçlü araçlardır. Doğru kavramı doğru yerde kullanmak, uygulamanızın daha okunaklı, daha bakımı kolay ve daha performanslı olmasını sağlar. Bu makalede, bu iki kavramı temel düzeyde inceledik. Daha derinlemesine bilgi edinmek için RxJS belgelerini inceleyebilirsiniz.
- Observable, zaman içinde birden fazla değer yayımlayan bir nesnedir.
- BehaviorSubject, Observable’ın özel bir türüdür ve başlangıç değeri vardır.
- Hangi kavramı kullanacağınız, uygulamanızın gereksinimlerine bağlıdır.
Umarım bu makale, Angular’da Observable ve BehaviorSubject konularını anlamanıza yardımcı olmuştur. Bir sonraki makalede görüşmek dileğiyle :)