Walaupun pada umumnya akan jarang kita membuat custom observable, kita akan lebih sering menggunakan observable yang sudah disediakan Angular, contoh routing. Namun memahami apa yang terjadi didalam observable dapat menambah wawasan kita.
Pada modul ini kita akan membuat custom observable versi kita. Kita akan buat Function Observable Interval sendiri.
Untuk itu kita perlu import modul Observable dari rxjs.
import { Observable, Subscription} from 'rxjs';
Syntax untuk membuat observable adalah
myCustomObservable = new new Observable(observer =>{
//code goes here
});
Untuk membuat custom Interval versi kita, digunakan setInterval dengan waktu per 1 detik. Dimana didalamnya, kita akan melakukan counting. Dan hasil counting akan di emit menggunakan method next().
Untuk membedakan dari Interval rxjs, disini counting akan ditambahkan 2.
const customInterval = new Observable(observer =>{
let count = 0;
setInterval(()=> {
observer.next(count);
count = count + 2;
}, 1000);
});
Berikut isi lengkap code pada home.component.ts dimana kita sudah menggunakan custom interval obserable.
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable, Subscription} from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
private mySubcription! : Subscription;
constructor() { }
ngOnInit() {
//intetval versi custom
const customInterval = new Observable(observer =>{
let count = 0;
setInterval(()=> {
observer.next(count);
count = count + 2 ;
}, 1000);
});
this.mySubcription = customInterval.subscribe(_count=>{
console.log(_count);
});
// inteval versi rxjs
// this.mySubcription = interval(1000).subscribe(_count=>{
// console.log(_count);
// })
}
ngOnDestroy(): void {
this.mySubcription.unsubscribe();
}
}
Sesuai ekspektasi, jika aplikasi dijalankan, fungsi interval akan berjalan.
Error Handling
Observable dapat menyebabkan error, untuk itu kita perlu melakukan error handling dengan menggunakan method error().
Untuk contoh, kita akan throw error yang sengaja kita buat. Misalnya ketika count > 6, kita throw error. Error yang terjadi harus kita catch pada saat melakukan observasi.
Perhatian: method error akan menyebabkan observable berhenti. Jadi tidak perlu dilakukan unsubscribe().
Berikut isi code setelah kita tambahkan error handling.
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable, Subscription} from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
private mySubcription! : Subscription;
constructor() { }
ngOnInit() {
//intetval versi custom
const customInterval = new Observable(observer =>{
let count = 0;
setInterval(()=> {
observer.next(count);
//contoh penggunaan error
if (count > 6){
observer.error(new Error('Count lebih besar dari 6'));
}
count = count + 2 ;
}, 1000);
});
//ditambahkan error handling.
this.mySubcription = customInterval.subscribe(_count=>{
console.log(_count);
}, err =>{
//code error handling goes here...
console.log(err);
alert(err.message);
});
// inteval versi rxjs
// this.mySubcription = interval(1000).subscribe(_count=>{
// console.log(_count);
// })
}
ngOnDestroy(): void {
this.mySubcription.unsubscribe();
}
}
Sesuai ekspektasi, ketika nilai count > 6, error akan terjadi. Untuk keperluan demo, kita hanya lakukan console log dan alert.
Menggunakan method completing()
Sesuai namanya Observable complete artinya, observable selesai dan berhenti emit value, tanpa error. Contoh complete adalah http request, akan complete jika response dari server sudah diperoleh.
Contoh code interval diatas tentu tidak akan pernah complete, karena kita akan terus emit nilai count baru. Untuk keperluan demo complete, kita akan tambahkan kondisi, pada code diatas.
Berikut isi home.component.ts setelah ditambahkan method complete.
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable, Subscription} from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
private mySubcription! : Subscription;
constructor() { }
ngOnInit() {
//intetval versi custom
const customInterval = new Observable(observer =>{
let count = 0;
setInterval(()=> {
observer.next(count);
//contoh penggunaan complete
if (count ===4){
observer.complete();
}
//contoh penggunaan error
if (count > 6){
observer.error(new Error('Count lebih besar dari 6'));
}
count = count + 2 ;
}, 1000);
});
//ditambahkan error handling.
this.mySubcription = customInterval.subscribe(_count=>{
console.log(_count);
}, err =>{
console.log(err);
alert(err.message);
}, () =>{
console.log("Inteval complete"); // handling complete
});
// inteval versi rxjs
// this.mySubcription = interval(1000).subscribe(_count=>{
// console.log(_count);
// })
}
ngOnDestroy(): void {
this.mySubcription.unsubscribe();
}
}
Sesuai ekspektasi, observable selesai sesuai kondisi yang kita tambahkan.