Angular uygulamalarında sunucu ile iletişim kurma ihtiyacı duyulduğunda, en yaygın olarak HttpClient modülü kullanılır. Bu modül, HTTP isteklerini göndermek ve almak için kullanılır. Ayrıca, bu HTTP isteklerini Observable olarak döndürür, bu nedenle RxJS ile entegrasyonu çok yaygındır.
Şimdi bir Product modeli için uçtan uca CRUD işlemlerinin olduğu örnek bir uygulama yapalım.
HttpClient Modülünün Eklenmesi
HTTP isteklerini yapabilmek için öncelikle HttpClientModule ün uygulamamızın modülüne eklenmesi gerekiyor.
app.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule // diğer modüller... ], // ... }) export class AppModule { } |
HTTP İstekleri
Örnek: ProductService ile CRUD İşlemleri
Burada API olarak JSON Server’ı kullanacağım. Bir önceki yazımda JSON Server’ın nasıl kullanıldığını detaylıca anlatmıştım. Öncelikle Angular Projesine JSON Server Kurma ve Çalıştırma yazısını okuyarak server’ı ayağa kaldırın ve sonrasında bu yazıda kaldığınız yerden devam edin.
product.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ProductService { private apiUrl = 'http://localhost:3000/products'; constructor(private http: HttpClient) { } // Tüm ürünleri getir getProducts(): Observable<Product[]> { return this.http.get<Product[]>(this.apiUrl); } // Tek bir ürün getir getProduct(id: number): Observable<Product> { return this.http.get<Product>(`${this.apiUrl}/${id}`); } // Ürün ekle addProduct(product: Product): Observable<Product> { return this.http.post<Product>(this.apiUrl, product); } // Ürün güncelle updateProduct(product: Product): Observable<Product> { return this.http.put<Product>(`${this.apiUrl}/${product.id}`, product); } // Ürün sil deleteProduct(id: number): Observable<any> { return this.http.delete(`${this.apiUrl}/${id}`); } } interface Product { id?: number; name: string; price: number; // diğer özellikler... } |
RxJS Entegrasyonu
HttpClient ın sağladığı metotlar, sonuçları Observable olarak döndürür. Bu, RxJS’nin Reactive Programming konseptine dayandığı anlamına gelir. Bu sayede, HTTP isteklerinin yanıtlarına tepki olarak senkron veya asenkron işlemleri zincirleme, birleştirme, hata yakalama gibi işlemleri kolaylıkla gerçekleştirebiliriz.
Örnek: Hata Yakalama
HTTP isteklerinde bir hata oluştuğunda, bu hatayı yakalayıp kullanıcıya uygun bir mesaj göstermek için RxJS’nin catchError operatörünü kullanabiliriz:
product.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ProductService { private apiUrl = 'http://localhost:3000/products'; constructor(private http: HttpClient) {} private handleError(error: HttpErrorResponse) { // Burada loglama yapılabilir. console.error(`Server error: ${error.status} - ${error.message}`); return throwError('Bir hata oluştu. Lütfen daha sonra tekrar deneyin.'); } getProducts(): Observable<Product[]> { return this.http.get<Product[]>(this.apiUrl).pipe(catchError(this.handleError)); } getProduct(id: number): Observable<Product> { return this.http.get<Product>(`${this.apiUrl}/${id}`).pipe(catchError(this.handleError)); } addProduct(product: Product): Observable<Product> { return this.http.post<Product>(this.apiUrl, product).pipe(catchError(this.handleError)); } updateProduct(product: Product): Observable<Product> { return this.http.put<Product>(`${this.apiUrl}/${product.id}`, product).pipe(catchError(this.handleError)); } deleteProduct(id: number): Observable<any> { return this.http.delete(`${this.apiUrl}/${id}`).pipe(catchError(this.handleError)); } } // Product model (interface) interface Product { id?: number; name: string; price: number; } |
Şimdi bileşen içinde bu servis metotlarının nasıl kullanılacağını gösterelim:
ProductService Kullanımı: ProductComponent
Öncelikle, bir ürün listesi göstermek, ürün eklemek, güncellemek ve silmek için basit bir bileşeni temsil edelim.
product.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import { Component, OnInit } from '@angular/core'; import { ProductService } from './product.service'; @Component({ selector: 'app-product', templateUrl: './product.component.html', }) export class ProductComponent implements OnInit { products: Product[] = []; selectedProduct: Product; errorMessage: string; constructor(private productService: ProductService) { } ngOnInit() { this.loadProducts(); } loadProducts() { this.productService.getProducts().subscribe(data => { this.products = data; }, error => { this.errorMessage = error }); } selectProduct(product: Product) { this.selectedProduct = product; } addProduct(product: Product) { this.productService.addProduct(product).subscribe(addedProduct => { this.products.push(addedProduct); }, error => { this.errorMessage = error }); } updateProduct() { if (this.selectedProduct) { this.productService.updateProduct(this.selectedProduct).subscribe(updatedProduct => { const index = this.products.findIndex(p => p.id === updatedProduct.id); if (index !== -1) { this.products[index] = updatedProduct; } }, error => { this.errorMessage = error }); } } deleteProduct(id: number) { this.productService.deleteProduct(id).subscribe(() => { this.products = this.products.filter(p => p.id !== id); }, error => { this.errorMessage = error }); } } |
product.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<div *ngIf="errorMessage"> {{ errorMessage }} </div> <ul> <li *ngFor="let product of products" (click)="selectProduct(product)"> {{ product.name }} - {{ product.price }} TL </li> </ul> <!-- Seçili ürünün detayları --> <div *ngIf="selectedProduct"> <h2>{{ selectedProduct.name }}</h2> <p>{{ selectedProduct.price }} TL</p> <button (click)="deleteProduct(selectedProduct.id)">Sil</button> <button (click)="updateProduct()">Güncelle</button> </div> <!-- Ürün Ekleme Formu (Basit Örnek) --> <div> <input #productName type="text" placeholder="Ürün Adı"> <input #productPrice type="number" placeholder="Ürün Fiyatı"> <button (click)="addProduct({name: productName.value, price: +productPrice.value})">Ürün Ekle</button> </div> |
Angular ile HTTP istekleri göndermek ve almak oldukça kolaydır. HttpClient modülü, modern web uygulamalarının ihtiyaç duyduğu çoğu işlevselliği sunar. Ayrıca, RxJS ile olan entegrasyonu sayesinde, HTTP yanıtlarını işleme veya hataları yönetme konusunda güçlü araçlara sahip oluruz.
Umarım “Angular HTTP İstekleri ve RxJS” başlıklı yazım sizin için faydalı olmuştur.
Şu yazılar da ilginizi çekebilir.
Angular Servisler ve Bağımlılık Enjeksiyonu
Yeni bir yazımda görüşmek üzere.
Happy coding!