I read about the signals in Angular and there are two methods to alter the current value: by set()
and update()
.
Angular has adapted Signals into the framework and have started to build a set of new features that utilize Signals as their cornerstone. Using update allows us to access the current value of the signal , and set allows us to set a new value without caring about the current value.
What puzzles me is that I don't understand how both are needed (although I see that each can be used). It's clear that I can. But why?
Let's say we define an instance like so.
siggy = signal(4);
Then, we can set an absolute value using both of the following ways.
this.siggy.set(1337);
this.siggy.update((a) => 1337);
But we also can use both of those to set a relative one (alter the current).
this.siggy.set(this.siggy() + 1);
this.siggy.update((a) => a + 1);
It seem superfluous to provide multiple ways to reach the same result. Such redundancy is a sign of bad design (or possibly syntactic sugar for DX purposes). I do not in any way suggest that the great folks on Angular team made a poor design! Nor do I see any increase in smoothness. (In fact, even the Angular blog mentions the usage of this.counter.set(this.counter()+1)
...)
My conclusion is that there are (edge) cases that I'm ignorant of. What am I missing?
edit
I kept on researching and discovered even more confusing facts. In addition to set()
and update()
, there's also mutate()
(So much for Complete Guide, thank you very much). And this one can be used as below (which I intuitively did).
let siggy = signal([1,2,3]);
...
this.siggy.mutate(a => a.push(4));
It compiles. The problem is that it won't do anything: no change, no update, no nothing! Apparently, I have to do like so.
this.siggy.mutate(a => a = [...a, 4]);
But that's redundant to the others! I can understand (although I disagree) that someone may want to use set()
to indicate a replacement, while keeping update()
for alterations. But even then, mutate()
brings no extra info as it's an update (which also sets it).
It seems like there's only siggy.alter()
, siggy.change()
and siggy.modify()
missing. It smells fishy to me. I'm certain it's me not getting the actual reason why set/update/mutate are all required.
What is the technical reason? What can't be done with each of those?
TL;DR: just set
is needed as you mention, update
was introduced for convenience & mutate
was eventually removed as essentially same as set
You can see the full discussion in the Signals APIs RFC