I guess a more interesting question is: how to handle http calls when a signal changes? There isn't a pattern defined for this one yet. Either you do it with toObservable -> http.get -> toSignal or using an effect in which you http.get and then do .set(result) - exactly what you suggested to void. Neither of the options are clean IMHO.
toObservable uses an effect under the hood. But what you have to keep in mind is, that you may not get all values that are set into that signal. You only get the last value whenever the effect is scheduled by the framework. When you really want to react to an event (like button click, input change etc.) you should use that as a source (through an observable, of course 😂).
@@larshanisch Agree! Speaking of Input, I think what would have been nice is if it could have behaved like FormControl (or BehaviorSubject for that matter) - from which you can either get the current value (snapshot) or the stream of changes, so that you can react granularly (e.g. make http requests), or even convert it to signal if you plan to further derive it. I know, you can do what I said with the old @Input and ngChanges, with an additional BehaviorSubject - but it would have been nicer to have a better (cleaner, more uniform) integration.
@@adrianspiridon old @Input only fires once in ngOnChanges, because "expression changed after check" 😄 I think of signals/toObservable as "automatic debounce". And I haven't had a situation where I got bitten by this. After all the rendering of a template is also an effect, so the bound signals are only read at specific timings. They are no events on every level... Most of the times I start requests either on clicks/submits or valueChanges of forms. So I'm fine!
Hmm, interesting. In most of the cases I run into, signals changing should not be the trigger to fetch data, instead that should be at the end of the stream created by an event (if we use unidirectional state patterns, which we should). What should trigger the http call is a user action, a route change, or some other event. So the event is the trigger, then process that action doing whatever you need, and at the end of it, change the state (similar to flux/redux pattern). Of course we will run in the situation you describe for example when a component input changes, then we need to react to that change, which is triggered by a signal change.. In those cases I use ngOnChanges, but in the Standalone Component RFC they say that they will remove this hook and instead recommend to use effect 🤷♂ I guess we are in the middle of a paradigm change and things need to settle down...
@@codeSurvivor You're right, we're in the middle of discovering new patterns with all these things. I really like using signals inside the template, but I wonder if implementing inputs as signals was the right way - maybe they should've been more like observables as the new output are. If I need to react to changes on inputs (and we all should do) then I just use toObservable (which uses an effect under the hood). After all signals have the advantage that they are in sync (if multiple inputs change at the "same" time). If I need to combine them into a stream, I first "computed" them into the thing I want to stream (so I'm glitch-free) and after that I use toObservable, so I don't have to use combineLatest or similar.
I guess a more interesting question is: how to handle http calls when a signal changes? There isn't a pattern defined for this one yet. Either you do it with toObservable -> http.get -> toSignal or using an effect in which you http.get and then do .set(result) - exactly what you suggested to void. Neither of the options are clean IMHO.
toObservable uses an effect under the hood. But what you have to keep in mind is, that you may not get all values that are set into that signal. You only get the last value whenever the effect is scheduled by the framework. When you really want to react to an event (like button click, input change etc.) you should use that as a source (through an observable, of course 😂).
@@larshanisch Agree! Speaking of Input, I think what would have been nice is if it could have behaved like FormControl (or BehaviorSubject for that matter) - from which you can either get the current value (snapshot) or the stream of changes, so that you can react granularly (e.g. make http requests), or even convert it to signal if you plan to further derive it. I know, you can do what I said with the old @Input and ngChanges, with an additional BehaviorSubject - but it would have been nicer to have a better (cleaner, more uniform) integration.
@@adrianspiridon old @Input only fires once in ngOnChanges, because "expression changed after check" 😄
I think of signals/toObservable as "automatic debounce". And I haven't had a situation where I got bitten by this. After all the rendering of a template is also an effect, so the bound signals are only read at specific timings. They are no events on every level...
Most of the times I start requests either on clicks/submits or valueChanges of forms. So I'm fine!
Hmm, interesting. In most of the cases I run into, signals changing should not be the trigger to fetch data, instead that should be at the end of the stream created by an event (if we use unidirectional state patterns, which we should). What should trigger the http call is a user action, a route change, or some other event. So the event is the trigger, then process that action doing whatever you need, and at the end of it, change the state (similar to flux/redux pattern).
Of course we will run in the situation you describe for example when a component input changes, then we need to react to that change, which is triggered by a signal change.. In those cases I use ngOnChanges, but in the Standalone Component RFC they say that they will remove this hook and instead recommend to use effect 🤷♂ I guess we are in the middle of a paradigm change and things need to settle down...
@@codeSurvivor You're right, we're in the middle of discovering new patterns with all these things. I really like using signals inside the template, but I wonder if implementing inputs as signals was the right way - maybe they should've been more like observables as the new output are.
If I need to react to changes on inputs (and we all should do) then I just use toObservable (which uses an effect under the hood). After all signals have the advantage that they are in sync (if multiple inputs change at the "same" time). If I need to combine them into a stream, I first "computed" them into the thing I want to stream (so I'm glitch-free) and after that I use toObservable, so I don't have to use combineLatest or similar.