Upon entering the realm of signals, our team stumbled upon a peculiar issue. Picture a scenario where a component has an effect on a signal which is a public member. In the constructor of the component, certain logic is executed to update the signal value multiple times. The assumption was that the effect would be triggered the same number of times as the updates to the signal value were made. However, this does not happen as expected. Instead, the effect is only fired for the first time after the entire initialization process of the component.
To see an example of this behavior, you can check out the demo I have created on StackBlitz DEMO
constructor() {
effect(() => {
this.effectLogs.push(JSON.stringify(this.valueSignal()));
if (this.valueSignal().length == 1 || this.valueSignal().length == 2) {
alert('Im never triggered');
}
});
this.insertFirstValue();
// possibly some other logic here
this.valueSignal.update((val) => [...val, 'constructor-1']);
setTimeout(() =>
this.valueSignal.update((val) => [...val, 'constructor-2'])
);
}
ngOnInit() {
this.valueSignal.update((val) => [...val, 'init-3']);
}
private insertFirstValue() {
this.valueSignal.update((val) => [...val, 'constructor-0']);
}
The result of the logs from setting up this effect look like this:
["constructor-0","constructor-1","init-3"]
["constructor-0","constructor-1","init-3","constructor-2"]
Since the initial effect already had 3 values pushed, the conditional alert in the effect never triggers. In our case, this complication extends further as our store feeding is based on conditions related to signal values, which exhibit the same unexpected behavior.
We began by isolating the problematic segment, hoping it was an error in our implementation. The demo demonstrates that it may be a general behavior. It could be a misunderstanding of how this should function at runtime, since we were unable to find documentation or solutions on platforms like Stack Overflow. In the example, I experimented by adding a button to input new entries twice, using computed properties, adding timeouts, but none seemed effective (except timeout).