New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
toSignal causes the signal to not being lazy-evaluated #55337
Comments
Hi! If we take the problem the other way around, wouldn't it be more surprising that the signal didn't subscribe eagerly, ie probably missing some values emited by the observable ? This wasn't an issue with the signals because you always get the latest value when reading them. Also can you give us more insight, what are the consequences for you that Edit: For the sake of completeness, this specific behavior can be implemented in userland. This has already been done by the ngxtension library with |
Hello! It depends on the point of view. In the signal world, basically everything is lazy-evaluated, so I wouldn't mind if the subscription doesn't happen immediately. We could catch any "missing" value with a piped The Additionally, Observables are cold/lazy as well until there is at least one active subscriber. And for me, creating a signal from an observable should not represent an active subscription until the signal itself is used somewhere. Thanks for the link, we will take a look at it. |
I think It's intended to be used like the That is, the |
@alxhub, You can see and try it here: |
Yeah, I should be more clear. |
These are valid points, however the We could create the signal from the observable when we actually need it (similarly how the Back to the original example: With signals, this can be easily implemented, because (from the docs): "Computed signals are both lazily evaluated and memoized"
The However, since the |
Which @angular/* package(s) are relevant/related to the feature request?
core
Description
First, we implemented a model (with validation logic and so on) with signals. Howver, since a signal/effect cannot be created anywhere (must be in injection context and outside of reactive context), we opted out and decided to use rxjs instead. This is fine, since the model is actually independent of Angular itself.
Additionally, we have a component that consists of pages. Each page can display validation errors found on that given page. The validation errors come from the model stated above.
Previously, while the model used signals, we were able to take advantage of the lazyness of the signal read operations. Consider the following simplified example:
So when we used (read) the
pageErrors
we only evaluated the model'serrors
if the page were ever visited.Using signals in components is comfortable so we used the
toSignal
from rxjs-interop, something like this:However, the
toSignal
call has a non-trivial consequence that it subscribes immediately, losing the lazy-evaluation aspect. The other way around (toObservable
) is pretty much the same, maybe even worse (since it useseffect
in its implementation that always runs at least once).Proposed solution
I think the
toSignal
andtoObservable
should get a deeper integration, allowing us to avoid use-cases like this. It would be the best if all computed signal properties (lazy + memoized) could be kept when usingtoSignal
- only subscribe when the signal value is read, and unsubscribe when the signal's refcount becomes 0 (all its listeners are unsubscribed).Alternatives considered
Currently there is no appropriate workaround, at least we could not find any. We could opt-out of using signals, but it has its advantages that we'd like to keep.
The text was updated successfully, but these errors were encountered: