Question to the Angular experts about Signals:
When you create a computed()
signal, dependencies are automatically tracked, but according to the docs only for signals that were previously read.
If I understand this correctly, would the following be problematic since the every
could potentially shortcircuit if the one of the first items is not selected, making the computed function only track a subset of the items?
const allSelected = computed(() => {
return selectableItems.every(item => item.selected());
});
To be clear: item.selected()
is a signal as well.
It seems to be running fine, but I want to be sure.
Your particular issue of concern shouldn't be an issue. For
selectableItems
to be true all items will have to be evaluated. If an item turns to false, it doesn't matter if an item with a greater index becomes false in the future because logically the result ofevery
will still be the same.That being said, you will have issues if
selectableItems
can have items added or removed.An extreme example is if
selectableItems
is empty whencomputed
is called. At that point, no signals will fire and the value will never be checked again.A less extreme issue would be if an item is added at a later point. The value of
allSelected
won't be evaluated until one of the previous items have their value changed. If all the old items are true and the new item is false, thenallSelected
will be wrong.If
selectableItems
can change, then a better design might be to makeselectableItems
a signal instead of all the individual items, and then use update when an item is changed.Advanced Solution
If you wanted to keep the logic of your array outside of your component you could even create your own signal. The solution below adds methods to a writable signal and uses undocumented but exported functions from core signal primitives.