Understanding RxJS with Angular

One of the biggest complaints I hear about Angular is not actually about Angular but rather about RxJS. People say it’s too difficult to learn, or it just seems weird. Well, I’m here to change all that. This article will be a short guide to help you understand how Observables work in the Angular ecosystem. Once you understand RxJS, the cool thing is that you can use it anywhere! That’s right; you can use RxJS in your React, Vue, or plain JavaScript projects as well. After all, it’s just a library, and it can be ported pretty much anywhere.

What is RxJs?

Before we get into the specifics, let’s get the basics out of the way. RxJS is a library for observing asynchronous events over time. Let’s give an example of what that might be. Let’s think about a chat app. We might want to observe a stream of messages to display to a user. Using RxJS, we would create an Observable of messages. Whenever someone sends a message, it would get sent to that Observable. In the app, we can then subscribe to that Observable. Then when a new message is added, we can react to that in the subscription. To sum it up, RxJS is a way to react to events using an Observable pattern.

How do we start using Observables?

I’m going to be going over Observables in the context of an Angular application. However, as I mentioned before, you can use RxJS anywhere. The first thing we’re going to do is create a new Angular application.

Once we have a new Angular app, we can create a service where we can start using Observables. This service is going to manage our app state which will be a simple string for demonstration purposes.

Inside this service, we’re going to use something called a BehaviorSubject. Before we look at the code, let’s go over what a Subject and BehaviorSubject is and why we would use one or the other.

Subject

Subjects are Observables that allow us to manage values on our own. Subjects have several methods that they use in order to manage their Observable values. The first method is the next() method. When you call this method you’re changing the value of the Observable. Whenever you call the next() method any subscribers will automatically get the new value.

The other method I want to mention is called asObservable(). This method essentially protects the Subject while still allowing observers to subscribe to it. Think of it like a private variable in a class. If we want to give another class/method access to our private variable we use setters and getters. It’s not much different with Subjects. Let’s have a look at an example.

We have a class and a private Subject. Then we use the asObservable() method and turn the observable variable in the class into a getter (essentially). Then we have an updateSubject method that takes in a string value and calls the next method on our private subject. The benefit of this is that we have more control over how new values are emitted to the subject.

Behavior Subject

A Behavior Subject is just like a regular Subject, in that we have all the same method, but with a few key differences. One difference between a Subject and Behavior Subject is that a Behavior Subject requires you to give a type as well as a starting value.

The last difference I want to point out is that a Behavior Subject is really useful for representing values over time. I know that’s kind of the point of Observables in general. However, with a Behavior Subject any new Subscribers will always receive the current value.

How does this work? We have two subscribers to a single Behavior Subject, but they subscribe at different times. We set “Jack” as the initial value of the Behavior Subject. So when we subscribe to that, we immediately get the initial value. Then we emit a new value of “Jill”, which will then become the default value. Once we get the second subscription it will immediately get the default value which is “Jill”. Then both subscribers will get the third value of “Roll down the hill”.

Creating a Simple State Management Service

So we’ve seen a lot about Subjects and Observables, so let’s put that to use and create a simple state management service. The state can take any shape you want, but to keep things simple, we’ll just make the state a simple string.

You may notice that we’re using a Behavior Subject instead of a regular Subject. Since we want to this to maintain the current value and send that to all new subscribers a Behavior Subject is ideal for this situation.

For our simple state management we have a private Behavior Subject with an initial value to it and then we make that publically accessible through the asObservable() method. Then we have our updateState method so we can post new values to the state. We’ll use this baseline class to do some data manipulation in the next section.

Manipulating Observable Data

So we have our state management class, but let’s say we need the string in a certain way, like to lowercase or to uppercase. We can use the handy-dandy pipe() method to start to fiddle with our data. Let’s see what we can do,

map

The map method works just like the array map method. We have a string and we want to turn it into a different string. In our case we’re just manipulating the casing of the string.

We can also return a different type of value. In the case of the numLetters function we can return a number instead of a string that indicates how many letters the current string is.

switchMap

This is one that I found really confusing when starting out. The switchMap function essentially transforms an Observable of one type to an Observable of a different type. The difference between map and switchMap is that the map function does not return another Observable, but instead returns a new value.

Let’s say you want to have a function that you can call that will send the current state value to an API. This is where we would want to use switchMap. When we call http.post we are getting an Observable back. If we tried to use the map function for this then we would get an error.

take

If you wanted to grab the first emitted value and no further values we can use the take method.

When we call the getFirst method we will ONLY get the default value of the Behavior Subject. We will not get any other emitted values.

Chaining Methods

Observable methods are really easy to chain. Let’s have a look at a method that combines all the things that we just talked about.

What will the chainedObservableMethods function do? When we start chaining methods they run sequentially. So the take(1) will limit this to the first emitted value of the state Observable. Then the map function will transform the value to either upper or lower case. Lastly, the switchMap function will send the transformed value to an API.

This is not an exhaustive list of Observable functions, but these are the ones that I often find myself using the most. I hope you’ve enjoyed this little Observable guide and found it useful!


If you’ve enjoyed this article, I’d love for you to join my mailing list, where I send out additional tips, tricks, and newsletters!

If you found this article helpful, interesting, or entertaining, feel free to buy me a coffee to help me continue to put out quality content!

Previous
Previous

Web Development Foundations

Next
Next

Why I Always use Angular