What is an 'Observable' in Reactive Programming / RxJS - Simple & Code Example
ReactiveX (Rx) is a popular library for writing asynchronous, event-driven code in many programming languages. One of the key concepts in RxJS, the JavaScript implementation of ReactiveX, is Observables. In this post, I'll explore what Observables are, how they work, and why they're useful in modern web development.
Overview of Observables in RxJS
Observables are a way to represent a stream of data over time. This stream of data can emit zero, one, or multiple values. Observables can be created from a variety of sources, such as events, user input, or data from a server.
Once created, Observables can be subscribed to, which means that an observer function is called each time the Observable emits a value. Observables are a fundamental concept in ReactiveX programming, and they provide a powerful and flexible way to write asynchronous code.
Here's an example of creating and subscribing to an Observable
Example in TypeScript
import { Observable } from 'rxjs';
const observable = new Observable<number>((observer) => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
const subscription = observable.subscribe((value) => console.log(value));
In this example, we create an Observable using the new Observable()
constructor, which takes a function that defines how the Observable will emit values over time. In this case, the function uses the setInterval()
method to emit a new value every second. We then subscribe to the Observable using the subscribe()
method, which takes an observer function that is called each time the Observable emits a value. Finally, we store the subscription object in a variable so that we can later unsubscribe from the Observable if needed.
Observable as a programming construct
It's important to note that an Observable is not a data type or data structure in the traditional sense. Rather, it's a programming construct that represents a stream of data over time. When you log an Observable using console.log
, it will show up as an object because it is an instance of the Observable class in the RxJS library.
Similarly, when you subscribe to an Observable using the subscribe()
method, it returns a Subscription object that represents the ongoing subscription. When you log a Subscription object, it will also show up as an object because it is an instance of the Subscription class.
Observables and "!!" (double negation operator)
As mentioned above - Observables are not a data type in RxJS in the same way that numbers or strings are data types. Instead, observables are a programming concept that represents a stream of values over time. You can think of an observable as a function that produces a sequence of values.
When you use the double negation operator "!!" on an observable in RxJS, it is used to convert the observable into a boolean value. The resulting boolean value is true
if the observable emits at least one value and false
otherwise.
For example, consider the following code in TypeScript
import { of, empty, Observable } from 'rxjs';
const obs: Observable<string> = of('hello', 'world');
const hasValues: boolean = !!obs;
console.log(hasValues); // true
In this code, we're using the Observable
type from the rxjs
library to define the obs
variable as an observable that emits strings. The !!
operator is then used to convert the observable obs
into a boolean value of true
, because it emits at least one value.
Similarly, we can use the empty
operator to create an observable that does not emit any values and convert it to a boolean value using the !!
operator:
import { empty, Observable } from 'rxjs';
const obs: Observable<string> = empty();
const hasValues: boolean = !!obs;
console.log(hasValues); // false
In this code, the obs
variable is an empty observable that does not emit any values. The !!
operator is then used to convert the observable obs
into a boolean value of false
, because it does not emit any values.
Using the !!
operator to convert an observable to a boolean can be useful in several scenarios, such as:
Checking if an API call returns any data: You can use an HTTP request to get data from a server, and then convert the resulting observable into a boolean to check if it returned any data.
Checking if a form field has a value: You can use an observable to track changes to a form field, and then convert the resulting observable into a boolean to check if it has any value.
Checking if an event stream has any events: You can use an observable to track a stream of events, and then convert the resulting observable into a boolean to check if it has emitted any events.
Checking for query parameters: You can use the
ActivatedRoute
service to get an observable that represents the current query parameters, and then use themap
operator to transform it into a boolean value based on the presence of a particular query parameter. This can be useful for setting application preferences or toggling features based on query parameters.
Is seeing a .sunscribe() a sure sign of working with Observables?
Yes, the subscribe
method is a sure sign that you're working with observables in RxJS. It is part of the Observable interface in RxJS, so it can only be used with observables. If you're not working with observables, you won't be able to use the subscribe
method.
In general, the subscribe
method is used to listen for and react to emitted values from an observable. If you're not working with observables, you may still be able to achieve similar functionality using other language features, such as events or callbacks.
For example, if you're working with the DOM in JavaScript, you can register event listeners using the addEventListener
method to listen for specific events, such as clicks or keypresses. Similarly, if you're working with asynchronous callbacks, you can pass a callback function to an asynchronous function to be executed when the function completes.
Observables Animation - CodePen
Observables are a powerful and flexible way to represent streams of data over time in RxJS. They allow developers to write asynchronous, event-driven code that is more efficient and easier to read and maintain. While Observables can take some time to learn, they are a key concept in ReactiveX programming and are widely used in modern web development.