RxJS - ajax & fromFetch operators
CRUD operations are fundamental features of any modern website or web application. Almost everyday we need to write code in the Front-End to communicate with the servers through the HTTP protocol (mostly consume data from REST Apis).
To communicate with the servers we mostly use Fetch api or Axios.
Fetch API
Fetch is a built-in api of modern browsers and the problem with the Fetch api is that the HTTP request made through Fetch api isn't cancelable. There is a workaround though - we can use AbortController
to cancel a request. But AbortController
isn't still widely supported.
Moreover, Fetch api doesn't have protection against XSRF attack.
fetch('url')
.then((response) => {
// Code for handling the response
})
.catch((error) => {
// Code for handling the error
});
Axios
Axios is a Javascript library used to make HTTP requests and it supports the ES6 Promise API. It also has client-side protection against XSRF. And we can cancel the HTTP requests using Axios.
axios.get('url')
.then((response) => {
// Code for handling the response
})
.catch((error) => {
// Code for handling the error
})
RxJS has a couple of operators that we can use to make HTTP requests. And the benefits of using RxJS operators are:
- RxJS operators return a stream of observables instead of a single promise
- RxJS observables are lazy. So, no HTTP request will be made until we subscribe to the observables
- The request is cancelable
- Safe against XSRF
- Tons of other powerful RxJS operators to customize the HTTP request or manipulate the data returned from the request
RxJS/ajax
RxJS/ajax creates an observable for an Ajax request with either a request object with url, headers, etc or a string for a URL.
import { ajax } from 'rxjs/ajax';
import { map, catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
const observable$ = ajax('url').pipe(
map(response => console.log(response)),
catchError(error => {
return throwError(error);
})
);
// Subscribing to observable
const subscription = observable$.subscribe({
next: (data) => console.log(data),
error: (err) => console.error(err),
complete: () => console.log('Request is complete')
});
// Unsubscribing from the observable
subscription.unsubscribe();
RxJS/fromFetch
fromFetch uses the Fetch api to make an HTTP request.import { of } from 'rxjs';
import { fromFetch } from 'rxjs/fetch';
import { switchMap, catchError } from 'rxjs/operators';
const data$ = fromFetch('url').pipe(
switchMap(response => {
if (response.ok) {
// OK return data
return response.json();
} else {
// Server is returning a status requiring the client to try something else.
return of({ error: true, message: `Error ${response.status}` });
}
}),
catchError(err => {
// Network or other error, handle appropriately
console.error(err);
return of({ error: true, message: err.message })
})
);
data$.subscribe({
next: result => console.log(result),
complete: () => console.log('done')
});