Back to the homepage
Angular

Angular Signals RxJS Interop From a Practical Example

Signals are Angular’s new reactive primitive that will improve the way we develop Angular Apps and the Developer’s Experience. It will also make a big difference in the change detection mechanism. 

In this article, I’ll explain how to create an Angular Typeahead component based on signals. Through this practical example, you will learn:

  • How to convert an RxJS observable to a signal
  • How to convert a signal to an observable

We love visuals, so let’s see what we are about to build.

The code below is the starting point. We will improve it by applying bindings based on signals.

Convert an RxJS observable to a signal

Let’s start small by getting some data from a service, converting them to a signal, and iterating over the items constructing the autocomplete options.

The get() method: 

  • Accepts a userId argument 
  • Throws an error if the userId is 100 (this is just a manual way to throw an error so that we can see how to apply basic error handling) 
  • Applies an artificial delay to help us display the loading indicator

But as mentioned above, we will see all of this step by step.

In the code below, we are using the toSignal method, which accepts an observable and returns a Signal based on the values produced by the observable. Please note the subscription to that observable is managed automatically for us, and it is cleared up when the injection context is getting destroyed.

Now let’s iterate over the post items in the HTML template. Note that we have to use the parenthesis to get the values from the Signal. This might sound like a bad approach since we’ve learned that binding to a method is getting called on every change detection cycle. However, this is not the case with signals. 

So far, we managed to complete the first step by only using the toSignal method. Now let’s try getting the user input and sending it to the service.

Convert a signal to an observable

The binding to the input field will be based on a signal as well. We will name that unserID with undefined being the initial value.

We need to apply a two-way binding, but since we cannot apply a banana in a box yet, we will separate the property binding using the event binding. (Note, at the time of writing this article, the Angular version is 16.0.4)

To send an HTTP call whenever the userId value changes, we can use a combination of the effect method and a BehaviorSubject, as seen below. 

While this approach works fine, it’s a bit verbose. It also requires the developer to subscribe/unsubscribe.

However, this seems to be a pattern we can use whenever we are combining a Signal along with some RxJS operators. That’s why the Angular Development Team created the toObservable method, which converts a signal to an observable and automatically handles the subscription/unsubscription. With this method, the code will become less verbose.

In the code above, we have the posts$ class field, which has a very short lifecycle since this is getting converted to a signal using the toSignal method. Let’s improve that a bit and also use a debounceTime operator.

Since we have converted the signal to an observable, we can apply RxJS operators to handle the loading state along with the error handling. We are handling the loading state with the isLoading signal<boolean>.

And that’s it! . 

I’ll finish this article by sharing some suggestions:

  • Try not to use the async pipe on the HTML template, as this will increase the change detection cycles
  • Try converting your component’s state to a signal
  • Don’t be afraid to use RxJS operators
  • Try using the effect on side effects that require logging or DOM manipulation.

You can find also a video that describes this example on my YouTube channel: Learn Angular Signals RxJS Interop From a Practical Example

Thanks for reading my article. 

About the author

Fanis Prodromou

I am a full-stack web developer with a passion for Angular and NodeJs. I live in Athens-Greece, and I have worked in many big companies. During my 14 years of coding, I have developed vast experience in code quality, application architecture, and application performance.

Being aware of how rapidly computer science and the tech aspects evolve, I try to stay up to date by attending conferences and meetups, by studying and trying new technologies. I love sharing my knowledge and help other developers.

“Sharing is Caring”

I teach Angular in enterprise companies via Code.Hub institute, I write articles and create YouTube videos.

Don’t miss anything! Subscribe to our newsletter. Stay up-to-date with the latest trends, tips, meetups, courses and be a part of a thriving community. The job market appreciates community members.

One comment

  1. Maciej

    Jak sobie poradzić z typowaniem toSignals? 🙂
    coś takiego wywali błąd:
    posts: Signal = toSignal(this.postsService.get());
    dodanie typu undefined niby to rozwiązauje ale zastanawiam się czy jakoś ładniej można to zrobić?

Leave a Reply

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