Angular toSignal(toObservable()) does return undefined

1.3k Views Asked by At

Hi assuming following code

import { Signal } from '@angular/core';
import { toObservable, toSignal } from '@angular/core/rxjs-interop';

const result = toSignal(toObservable(signal(10)))
console.log(result()) // does log undefined instead of 10

I would assume that result() will return 10 instead of undefined. However it seems like I'm missing something but I dunno what.

2

There are 2 best solutions below

0
On BEST ANSWER

This is an effect you're seeing is due to the current implementation of toObservable. If you look at the implementation you'll see that the emissions are created inside of an effect. Effects always run asynchronously during the change detection cycle. So you can't count on them running immediately.

If you think about it, this is the best that could be done. For example, it could've performed an initial emission before the watcher (subject.next(source())), but...

  • Without any guards, the first execution of the effect would potentially cause a double emission of the same value.
  • A boolean variable could've been created to skip the emission from the first execution of the effect, but there's no way of knowing if the source signal changed before that first effect ran.
  • Instead of a boolean, the watcher could compare the current value with the source value and only emit changes, but maybe the the equal function on the signal was set to something that wanted repeated emissions, and now you're potentially omitting valid emissions.

So take it for granted that the first emission by an observable created from toObservable will be delayed.

2
On

The return type of toSignal has Signal<number | undefined>

Before the Observable emits its first value, the Signal will return undefined

To avoid this, either an initialValue can be passed or the requireSync option enable

const result = toSignal(toObservable(signal(10)),{ initialValue: 10 })
console.log(result()) //logs intial value 10

You can read More about here