Sub-RFC 4 for Angular Signals sparks interesting discussion started by RxJS author — Ben Lesh
Published: 2023-04-10 12:41:32



![Generated by MidJourney AI](https://cdn-images-1.medium.com/max/3072/1*zZN93gkIlcet722Ox21hBQ.jpeg)

_Custom graphics generated by MidJounrey AI_

Before we dive in to the interesting discussion — it’s essential to know that everyone has the opportunity to actively participate and express their opinions on upcoming Angular modifications in public discussions under existing sub-RFCs. **The focus here is [sub-RFC 4](https://github.com/angular/angular/discussions/49681).**

## What are Signals and sub-RFC4?

Quick intro on the whole topic of Angular Signals. **In a nutshell Signals are new approach to reactivity in Angular**, simplifying reactivity while simultaneously enabling fine-tuned control over component updates.

Sub-RFC 4 is taking on the important topic of interoperability with RxJS Observables, a fundamental way of how we manage reactivity in Angular applications today.

## Signals and RxJS compatibility

Seamless compatibility with current RxJS-based applications and libraries is what Angular Signals aim for.

[Sub-RFC 4](https://github.com/angular/angular/discussions/49681) presents two innovative APIs, `toObservable` and `toSignal`, conversation between Observables and Signals. You can find them in `@angular/core/rxjs-interop`. Keep in mind it’s all work in progress.

## toSignal

convert an RxJS Observable to an Angular Signal using `toSignal`:

    const counter: Signal<number> = toSignal(counter$);

Internally, `toSignal` subscribes to the supplied Observable and updates the returned Signal each time the Observable emits a value. The subscription is established immediately, and **Angular will automatically unsubscribe when the context in which it was created is destroyed.**

### Initial value

Using `toSingal`, you can provide a default value to use if the Observable hasn’t emitted by the time the Signal is read:

    const secondsObs = interval(5000);
    const seconds = toSignal(secondsObs, 0);
    effect(() => {
      console.log(seconds());
    });

## Error and completion states

Signals function as value wrappers, notifying consumers when the value changes. Observables, however, have three types of notifications: `next`, `error`, and `complete`. When an Observer created by `toSignal` is notified of an `error`, it will throw the error the next time the Signal is read. To handle the error at the Signal usage point, you can employ `catchError` on the Observable side or computed on the Signal side.

**Signals lack a “`complete`” concept**, but you can represent the completion state using an alternative signal or the `materialize` operator.

## toObservable

Signal to Observable? Use `toObservable` - it takes an Angular Signal and returns an Observable. It does this by creating an effect when the Observable is subscribed to, which takes values from the signal and streams them to subscribers.

```
const count: Observable<number> = toObservable(mySignal);

```
The Observable produced by `toObservable` uses an effect to send the next value. All values emitted by the `toObservable` Observable are delivered asynchronously.

If you want to get the first value synchronously, you can use the startWith operator:

```
const obs$ = toObservable(mySignal).pipe(startWith(mySignal()));
```


## Lifecycle and Cleanup

When a `toObservable` Observable is subscribed, it creates an effect to monitor the signal, which exists until that subscriber unsubscribes.

This differs from `toSignal`, which automatically cleans up its subscription when the context in which it was created is destroyed.

If desired, it’s straightforward to tie the resulting Observable to the component’s lifecycle manually:

```
const myValue$ = toObservable(myValue).pipe(takeUntil(this.destroy$))
```


## **Conclusion**

All of this has been created to allow easy way of bridging RxJS Observables and Signals. Angular team wants to minimise the impact of changes allowing us to easily work with both approaches.

![Generated by MidJourney AI](https://cdn-images-1.medium.com/max/3072/1*ZGdEeMZd5bmYqvmt0IksbA.png)

## The Angular Signals and Observables Debate

Now to the more interesting part. The [sub-RFC 4](https://github.com/angular/angular/discussions/49681) proposal sparked a **discussion about the possibilities of integrating Angular Signals with Observables**. It all comes down to whether Angular Signals should adopt globally understood common interop points like `Symbol.asyncIterator` and `Symbol.observable`.

![](https://cdn-images-1.medium.com/max/3200/1*vnfMd52sOljhCvBX9H9zog.jpeg)

## Ben Lesh on his vision

**Ben Lesh** thinks that making signals fit observable chains directly is a good idea, stating that Signals inherently possess a time dimension that makes them well-suited for this. **By adopting common interop points, Angular Signals could achieve better compatibility across various platforms.**

![](https://cdn-images-1.medium.com/max/2000/1*KwcjOGMBfpXRenoUtyz0dQ.jpeg)

## Alex Rickabaugh pointing out potential issues

However, **Alex Rickabaugh** mentions that team has been thinking about this approach, **explaining that Angular Signals have unique characteristics that make it challenging to safely read them during the change propagation phase**.

Additionally, signals require an injection context, which could result in surprising and burdensome requirements when used inside Observable pipelines. Alex states that signals are not Observables, and **converting between them should be an intentional operation to ensure a well-considered application architecture.**

## The Angular Team’s Stance

Angular team remains firm in their decision not to implement `InteropObservable` or any `Subscribable` interface for Angular Signals. Although this means no immediate changes to the framework, the debate has undoubtedly generated **valuable insights and raised important questions about the future of Angular Signals and Observables.**

![Generated by MidJourney AI](https://cdn-images-1.medium.com/max/3072/1*Jw7JrEzB4HCy7PhOVNYVJw.png)

## Stay informed

The Angular [sub-RFC 4](https://github.com/angular/angular/discussions/49681) debate highlights the challenges and considerations involved in enhancing Angular. As the community continues to explore these ideas — discussions like this are going to happen in the end resulting in better final implementation. **I believe it’s important to stay informed about such conversations and even participate if you feel like you have a valuable point to add to discussion.**

---

### I hope you liked my article!

If you did you might also like what I am doing on **Twitter**. I am hosting live Twitter Spaces about Angular with GDEs & industry experts! You can participate live, ask your questions or watch replays in a form of short clips :)

If you are interested drop me a follow on **Twitter [@DanielGlejzner](https://twitter.com/DanielGlejzner) — would mean a lot :). Thank You!**