I have a component with 2 input signals that have no value initially. I need to send http request only one time and it should be the moment both signals have value.
What is the proper way to do it? Should I use effect that I manually destroy after first execution or is there some other way?
If for some reason you don't want to use EffectRef.destroy() or a rxjs approach, then here is a signals-based solution that takes advantage of how changes are tracked in an effect.
export class DemoComponent {
readonly value1 = signal<string | undefined>(undefined);
readonly value2 = signal<string | undefined>(undefined);
constructor() {
effect(() => {
// if the untracked check is true then this will never updated again.
if (untracked(() => !!this.value1() && !!this.value2())) {
// Do initialization tasks...
return; // prevent signals being checked again by returning early.
}
this.value1();
this.value2();
});
}
}
This approach leverages the behavior of effect functions, which only execute when a tracked signal changes. To ensure the correct behavior, the initialization condition is evaluated inside an untracked function. If the condition is true, the initialization code runs, and the function exits before any signals are tracked. However, if the condition is false, all necessary signals are accessed, even though their values are not used, ensuring they are properly tracked.
The advantage of this method is that it keeps all logic self-contained within the effect function, preventing side effects. However, there is a downside: the double reads can feel hacky, and their purpose might become unclear, especially if additional signals are needed as requirements evolve. This risk can be mitigated by placing all necessary signals in an array and using that array for both the condition check and the tracking reads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With