RxJS is a javascript library that brings the concept of "reactive programming" to the web.
Reactive programming is just a different way of building software applications. Essentially, your software is built to "react" to changes that happen (like click events, data being fetched, etc.)
An Observable is basically a function that can return a stream of data to an observer over time.
Observer is there to execute some code whenever it receives a new value from the observable. We connect observable to the observer through subscription using a method called subscribe.
So, observer can implement (in subscribe method) upto three methods next, error, and complete.
next()
will be called by the observable whenever it emmits a new value.error()
will be called whenver observable throws an error.complete()
is called whenver the observabe is done.
var observer = {
next: function (value) {
console.log(value);
},
error: function (error) {
console.log(error);
},
complete: function () {
console.log('Completed');
}
};
var subscription = Rx.Observable.create(function (obs) {
obs.next('A value');
//obs.error('Error');
obs.complete();
})
.subscribe(observer);
we are going to call an existing api using JSON placehoder which will return data about Blogs as an observable.
We will manipulate that data using RxJS operators. Here we will show the final result using subscription.
To scaffold a new angular application. See:
To use HttpClient service in angular. See:
To setup Base Url as environment variable in development environment we will simple put it in environment.ts file.
export const environment = {
production: false,
baseUrl: 'https://jsonplaceholder.typicode.com/'
};
To understand more about environment configuration. See 9configuring application environment](https://angular.io/guide/build)
API has a function /posts
that returns a array of object that looks like.
To capture this array in type safe manner we will introduce a TypeScript interface matching the same property names as of returned objects.
We will create a folde called models
to contain all of our models. In it we will create a file called posts.ts
export interface Blog {
userId: number;
id: number;
title: string;
body: string;
}
To fetch data from api we will create an angular service Blog Service. We will create a folder called services
to contain all the services in the application. In this folder we will run the command.
ng generate service blog
This will scaffold a new service in our application in the file blog.service.ts with following code
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class BlogService {
constructor() { }
}
We will dependency inject HttpClient in BlogService to call the api in a function called getBlogPosts. This function will use base url from the environment to construct function url and will use Blog interface to deserialize and return objects into type safe array.
@Injectable({
providedIn: 'root'
})
export class BlogService {
// depdendency injecting HttpClient
constructor(private httpClient: HttpClient) { }
// returning type safe Blog array
getBlogPosts(): Observable<Blog[]> {
// calling HttpClient get method to call the API
// contructing the URL using the environment variable and path to the function (i.e., posts)
return this.httpClient.get<Blog[]>(environment.baseUrl + 'posts');
}
}
We will depdency inject the BlogService
in the AppComponent and call the getBlogPosts
method in OnInit
life cycle hook to get the observable.
this.blogService
.getBlogPosts()
.subscribe(response => { this.blogs = response; });
An operator is a pure function which takes in observable as input and the output is also an observable.
It’s a standalone function and a method on the Observable interface that can be used to combine multiple RxJS operators to compose asynchronous operations.
Applies a given function to each value emitted by the source Observable, and emits the resulting values as an Observable.
Filter items emitted by the source Observable by only emitting those that satisfy a specified condition.
// declare and initialize an empty type safe array
blogs: Blog[] = [];
// dependency injecting for the BlogService
constructor(private blogService: BlogService) {
}
ngOnInit(): void {
// calling the service
this.blogService.getBlogPosts()
// filtering the top 10 posts based on criteria using lambda expression
.pipe(map(p => p.filter(x => x.id < 10)))
.subscribe(response => {
this.blogs = response;
});
}