Netanel Basal

Learn development with great articles

Follow publication

Handling Errors with toSignal in Angular

When working with Angular, the toSignal function is a powerful tool for converting an Observable into a reactive signal. However, there's a nuanced behavior you need to be aware of, especially when dealing with errors emitted by the Observable.

By default, when the Observable associated with a signal emits an error, Angular’s toSignal will propagate this error every time you attempt to read the signal’s value. We can see this behaviour in the source code:

return computed(
() => {
const current = state();
switch (current.kind) {
case StateKind.Value:
return current.value;
case StateKind.Error:
// 👇👇👇
throw current.error; // Throws the error
}
}
);

This approach has significant implications. If your application has a global error handler, it will be invoked each time the signal’s value is accessed after an error has been emitted. This behavior might not align with your expectations, especially if you’re accustomed to handling errors in the way the async pipe does.

To better control error handling and mimic the behavior of Angular’s async pipe, you can use the rejectErrors option. When this option is enabled, errors from the Observable's error channel are thrown back to RxJS, where they are processed as uncaught exceptions. Here's what this looks like in practice:

const sub = source.subscribe({
next: (value) => state.set({ kind: StateKind.Value, value }),
error: (error) => {
// 👇👇👇
if (options?.rejectErrors) {
throw error;
}

state.set({ kind: StateKind.Error, error });
},
});

By setting rejectErrors to true, the signal created by toSignal will maintain the last successfully emitted value indefinitely. This is because Observables that emit an error do not produce further values. Essentially, the signal will "freeze" at the last good value, ignoring any subsequent errors, which can be particularly useful in scenarios where maintaining application stability is a priority.

Follow me on Medium or Twitter to read more about Angular and JS!

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Netanel Basal
Netanel Basal
Netanel Basal
Netanel Basal

Written by Netanel Basal

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.

No responses yet

Write a response