RxJS is a JavaScript library that enables the creation of asynchronous and event-based programs. The main type is the Observable
and a suite of functions and operators are provided to make it easier to work with the data coming through. This series will detail those operators (and a few stand-alone functions) and provide examples of their use.
In this post, we’re going to cover the of
function.
What does it do?
Strictly speaking, this isn’t an operator, but it is useful in its own right. I’ll be making use of it to simplify the examples presented.
The of
function allows us to turn a normal value, or series of values, into an observable. When we subscribe to this observable it will emit all the values that were provided to it. Once all values have been emitted it will be automatically completed.
Example
of
can be used just like we would any other observable:
import { of } from 'rxjs';
of('Test Value')
.subscribe(x => {
console.log(x);
});
Running this we will see
Test Value
The of
function is that simple. It takes in a value and gives us back an observable.
If we need the observable to emit multiple values we can do that by passing multiple values to the of
function:
import { of } from 'rxjs';
of('Test Value', 'And a second', 'Third and final')
.subscribe(x => {
console.log(x);
});
Test Value
And a second
Third and final
While it is simple, don’t underestimate its utility. Here are a few example use cases:
Unit testing - Being able to mock external dependencies is essential for effective unit testing. The of
function makes it easy to specify return values from observable functions.
Caching - If we’ve got an observable call that we know doesn’t change often, we may want to cache the result. On subsequent calls, we can just return the cached result rather than running the query repeatedly. of
allows us to return the cached value as an observable, meaning the calling code doesn’t need any knowledge of the internal handling to process the result.
Error handling - If we have an HTTP call implemented using observables (like the Angular HTTP client) there is a chance of errors. While these should always be handled, we might not want to throw the exception back to the initiator. In this case, we can handle the error (using the catchError
operator) and use of
to return a default value.
These are just a few of the areas I see this used in. The point is, it comes in handy more often than you might expect.
The source code for this example is available on GitHub: