Categories
JavaScript Rxjs

Some Useful Rxjs Creation Operators

Spread the love

Rxjs is a library for doing reactive programming. Creation operators are useful for generating data from various data sources to be subscribed to by Observers.

In this article, we’ll look at some creation operators from Rxjs.

Ajax

We can use the ajax() operator to fetch response objects returned from APIs.

For example, we can use it as follows:

const observable = ajax(`https://api.github.com/meta`).pipe()  
  map(response => {  
    console.log(response);  
    return response;  
  }),  
  catchError(error => {  
    console.log(error);  
    return of(error);  
  })  
);

observable.subscribe(res => console.log(res));

We pipe the data from the response with the map operator. Also, we can catch HTTP errors with the catchError operator.

Also, we can use ajax.getJSON() to simplify the operation as follows:

import { ajax } from "rxjs/ajax";  
import { map, catchError } from "rxjs/operators";  
import { of } from "rxjs";

const observable = ajax.getJSON(`https://api.github.com/meta`).pipe()  
  map(response => {  
    console.log(response);  
    return response;  
  }),  
  catchError(error => {  
    console.log("error: ", error);  
    return of(error);  
  })  
);

observable.subscribe(res => console.log(res));

Note that in both examples, we return the response in the callback of the map that we passed into the map operator.

It also works for POST requests:

import { ajax } from "rxjs/ajax";  
import { map, catchError } from "rxjs/operators";  
import { of } from "rxjs";

const observable = ajax({  
  url: "https://jsonplaceholder.typicode.com/posts",  
  method: "POST",  
  headers: {  
    "Content-Type": "application/json"  
  },  
  body: {  
    id: 1,  
    title: "title",  
    body: "body",  
    userId: 1  
  }  
}).pipe(  
  map(response => console.log("response: ", response)),  
  catchError(error => {  
    console.log("error: ", error);  
    return of(error);  
  })  
);

observable.subscribe(res => console.log(res));

As we can see, we can set headers and body of the request, so ajax can deal with most HTTP requests.

Errors can also be caught with the catchError operator that we pipe in:

import { ajax } from "rxjs/ajax";  
import { map, catchError } from "rxjs/operators";  
import { of } from "rxjs";

const observable = ajax(`https://api.github.com/404`).pipe()  
  map(response => {  
    console.log(response);  
    return response;  
  }),  
  catchError(error => {  
    console.log(error);  
    return of(error);  
  })  
);

observable.subscribe(res => console.log(res));

bindCallback

bindCallback converts a callback API to a function that returns an Observable.

It can convert a function with parameters to an Observable by emitting the parameters.

It takes 3 arguments. The first is a function, which takes a callback function as a parameter. Whatever is passed into the callback function will be emitted by the Observable.

The second argument is an optional resultSelector . We can pass in a function to select the emitted results here.

The last argument is an optional scheduler. We can pass in a scheduler if we want to change the way the callback function in the first argument is scheduled to be called.

import { bindCallback } from "rxjs";

const foo = fn => {  
  fn("a", "b", "c");  
};

const observableFn = bindCallback(foo);  
observableFn().subscribe(res => console.log(res));

Then we’ll see 'a' , 'b' and 'c' since we passed them into our fn callback function, which is a parameter of foo .

Then we return a function that returns an Observable with the bindCallback function. Then we can subscribe to the returned Observable.

defer

defer lets us create an Observable that are only created when a subscription is made.

It takes one argument, which is an Observable factory function. For example, we can write:

import { defer, of } from "rxjs";
const clicksOrInterval = defer(() => {  
  return Math.random() > 0.5 ? of([1, 2, 3]) : of([4, 5, 6]);  
});  

clicksOrInterval.subscribe(x => console.log(x));

Then we can have an Observable that either subscribes to of([1, 2, 3]) or of([4, 5, 6]) depending on whether Math.random() return 0.5 or less or bigger than 0.5.

empty

Creates an Observable that emits nothing to Observers except for complete notification.

It takes one optional argument, which is the scheduler that we want to use.

For example, we can use it as follows:

import { empty } from "rxjs";
const result = empty();  
result.subscribe(x => console.log(x));

Then we should see nothing logged.

Another example would be to emit the value 'odd' when odd numbers are emitted from the original Observable:

import { empty, interval, of } from "rxjs";  
import { mergeMap } from "rxjs/operators";const interval$ = interval(1000);  
const result = interval$.pipe(  
  mergeMap(x => (x % 2 === 1 ? of("odd") : empty()))  
);  
result.subscribe(x => console.log(x));

from

from creates an Observable from an array, array-like object, a promise, iterable object or Observable-like object.

It takes 2 arguments, which is an array, array-like object, a promise, iterable object or Observable-like object.

The other argument is an optional argument, which is a scheduler.

For example, we can use it as follows:

import { from } from "rxjs";
const array = [1, 2, 3];  
const result = from(array);result.subscribe(x => console.log(x));

We can also use it to convert a promise to an Observable as follows:

import { from } from "rxjs";

const promise = Promise.resolve(1);  
const result = from(promise);
result.subscribe(x => console.log(x));

This is handy for situations where we want to do that, like converting fetch API promises to Observables.

As we can see, the creation operators are pretty useful for turning various data sources to Observables.

We have the ajax operator for getting HTTP request responses. The bindCallback function turns callback arguments into Observable data. defer let us create Observables on the fly when something subscribes to the Observable returned by the defer operator.

Finally, we have the empty operator to create an Observable that emits nothing, and a from operator to create Observables from an array, array-like object, a promise, iterable object or Observable-like object.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *