Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Angular 4 – Observable İle Asenkron Http Service İşlemleri

Merhaba,

Angular 4 uygulamalarında Http Service ile çalışırken Observable ile süreci asenkron bir şekilde yürütebilmekteyiz. Aslında Observable yapısı Angular 4 içinde sadece http isteklerinde kullanacağımız bir yapı değildir. Birçok farklı noktada kendisinden istifade edebileceğimiz nimetleri mevcuttur. Lakin biz bu içeriğimizde Observable modülünün Http servislerindeki katkısına değinecek, irdeleyecek ve değerlendireceğiz.

Observable’ın Çalışma Mantığı

Observable; bilinen prosedürel programlamada olduğu gibi ardışıl olarak işlenmiş kodsal süreçleri adım adım yerine getirip tepki göstermekten ziyade, olay bazlı duyarlılık sergilemektedir ve belli başlı olaylar cereyan ettiği zaman refleks göstermektedir.

Bu durumu şöyle özetleyebiliriz;

Observable; herhangi bir akıma/olaya abone olur ve o akımı/olayı sürekli dinler. Süreçte, dinlenen akım/olay içerisinde herhangi bir etki olursa önceden tanımlanan faatliyetleri uygular. Bu duruma Stream Subscription denmektedir.

Yukarıda Stream Subscription kavramının kullanılması sakın sizlerde http isteklerinin stream olarak geldiğini düşündürmesin. Stream Subscription; http isteklerinden bağımsız bir şekilde, Observable modelinin tasarımsal yapısıyla alakalıdır. Bu mantığı daha da anlayabilmek için Observer Design Pattern konusuna göz atabilirsiniz. Yapısal olarak bu tasarım, belirli olayları takip etmekte ve tepki göstermekte olduğu için akım/olay aboneliği Observable’in mantıksal getirisinden başka birşey değildir.

Tüm bunlardan anlayacağımız Observable yapısı sadece http açısından ele alınamayacak kadar geniş kapsamlı bir konudur. Birçok farklı işlemde, farklı amaçlar uğruna kullanabileceğimiz bir yapıdır. Özellikle asenkron yapıların kontrolünü bu esnek ve yetenekli yapı sayesinde rahatlıkla gerçekleştirebilmekteyiz.

Observable İle Http Servis Kullanımı

Observable ile Http servis kullanımına gelirsek eğer öncelikle yapmamız gereken aşağıdaki modülleri uygulamanızın ilgili component, servis vs. import etmemiz gerekmektedir.

  1. Http;
    @angular/http“‘den import edilecektir. Http istekleri yapmak için kullanacağımız modüldür.
  2. Response;
    @angular/http“‘den import edilecektir. Http isteğine karşılık gelen cevapları yönetmemiz için gerekli nesneleri içeren modüldür.
  3. Observable;
    rxjs/Observable“‘den import edilecektir.
    Olay takibi ve Asenkron işlemler için kullanacağımız nesnemizi içeren modüldür.
  4. map;
    rxjs/add/operator/map“‘den import edilecektir. Map, gelen response datayı istediğimiz bir veri tipinde ya da formatta elde etmek için kullanılır.
  5. do;
    rxjs/add/operator/do“‘den import edilecektir. Do, yapılan asenkron operasyon işlemi bittiğinde yapılacak işlemleri belirlemek için kullanılır.
  6. catch;
    rxjs/add/operator/catch“‘den import edilecektir. Süreçte karşılaşabileceğimiz olası hataları kontrol etmemizi sağlar.

Node.js; ReactiveX modüllerine rahatlıkla erişebilmemiz için ilgili modüllere “rxjs” aliasını tanımlamıştır. (Bknz : Reactive Programming)

import { Injectable } from '@angular/core';
import { Http, Response } from "@angular/http";
import { Observable } from "rxjs/Observable";
import "rxjs/add/operator/map";
import "rxjs/add/operator/do";
import "rxjs/add/operator/catch";
import { User } from '../entitys/user';
@Injectable()
export class UserService {
  constructor(private http: Http) { }
  getUsers(): Observable<User[]> {
    return this.http.get("http://jsonplaceholder.typicode.com/users")
      .map(response => response.json());
  }
}

Ben makalemizde bir servis üzerinden örneklendirme yapacağım için ilgili modülleri “UserService” isimli servise eklemiş bulunuyorum. Geriye “Observable<User[]>” tipinden nesne dönen “getUsers” fonksiyonumuz içerisinde http ile harici kaynaktan yaptığı talep neticesini bizlere json formatında dönmektedir.

Tabi ki de http servisini kullandığımdan dolayı ana modülün “app.module.ts” dosyasına “HttpModule” nesnesini import ederek “imports” dizinine ekliyorum.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
import { HttpModule } from '@angular/http';
import { UserService } from './services/user.service';
@NgModule({
  declarations: [
    AppComponent,
    UserComponent
  ],
  imports: [
    BrowserModule, HttpModule
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Servisimizin içerisinde kullandığı “User” sınıfınıda aşağıdaki gibi tasarlıyorum.

export class User {
    id: number;
    name: string;
    username: string;
    email: string;
    adress: {
        street: string;
        suite: string;
        city: string;
        zipcode: string;
        geo: {
            lat: number;
            lng: number;
        };
    };
    phone: string;
    website: string;
    company: {
        name: string;
        catchPhrase: string;
        bs: string;
    };
}

Ardından “User” isminde bir component oluşturuyorum ve “user.component.ts” dosyasının içerisini aşağıdaki gibi inşa ediyorum.

import { Component, OnInit } from '@angular/core';
import { UserService } from '../services/user.service';
import { User } from '../entitys/user';
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css'],
  providers: []
})
export class UserComponent implements OnInit {
  userDatas: User[];
  constructor(private userService: UserService) { }
  ngOnInit() {
    this.userService.getUsers().subscribe(d => this.userDatas = d);
  }
}

Dikkat ederseniz “UserComponent” sınıfının constructerından elde edilen “UserService” nesnesi “providers” içerisinde verilmemiştir. Bunun sebebi ise ana modül içerisindeki “providers”a verilmiş olmasıdır. Yani ana modül içerisinde verildiği için burada verilmesine gerek duyulmamaktadır. Sayfayı biraz yukarı çıkarıp ana modülün kodlarını incelerseniz ne demek istediğimi daha net anlayacaksınız.

“ngOnInit” metodunda “UserService” içerisindeki “getUsers” metodu çağrılmakta ve işlem başarılı sonuçlandıysa “subscribe” fonksiyonu ile “User[]” dizi tipinden olan “userDatas” değişkenine elde edilen veriler atanmaktadır.

Son olarak ilgili componentimizin html sayfasını aşağıdaki gibi düzeltiyorum.

<table style="width:70%;">
  <thead>
    <tr>
      <td>Name</td>
      <td>User Name</td>
      <td>E-Mail</td>
      <td>Adress</td>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let data of userDatas">
      <td>{{data.name}}</td>
      <td>{{data.username}}</td>
      <td>{{data.email}}</td>
      <td style="width: 550px;">
        {{data.street}} | {{data.address.suite}} | {{data.address.zipcode}} |{{data.address.city}} | x : {{data.address.geo.lat}}
        | y : {{data.address.geo.lng}}<br>{{data.naber}}
      </td>
    </tr>
  </tbody>
</table>

Uygulamayı kaydedip, yayınladıktan sonra aşağıdaki ekran görüntüsüne benzer sonuçla karşılaşmaktayız.
Angular 4 - Http Service Nasıl Kullanılır?

Görüldüğü üzere http servislerini kullanırken Observable nimetlerinden bu şekilde faydalanabilmekteyiz.

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir