Search code examples
angularangular-signals

Angular toSignal(toObservable()) does return undefined


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.


Solution

  • 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.