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
selectableItemsto 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 ofeverywill still be the same.That being said, you will have issues if
selectableItemscan have items added or removed.An extreme example is if
selectableItemsis empty whencomputedis 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
allSelectedwon'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, thenallSelectedwill be wrong.If
selectableItemscan change, then a better design might be to makeselectableItemsa 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.