0

I am using Angular 16 and just started with signals. Those make working with ngrx even better. When transitioning I found myself presented with something that can be abstracted to this:

const state = {
 someArray: [1, 5, 7]
}

export const selectArray = createSelector(
  state,
  (state) => state.someArray
);

export const selectFirst = createSelector(
  selectArray,
  (someArray) => someArray[0]
);

export const selectLast = createSelector(
  selectArray,
  (someArray) => someArray[state.someArray.length-1]
);

export const selectLastMinusFirst = createSelector(
  [selectFirst, selectLast],
  (first, last) =>
    last - first
);

Now with signals this could be rewritten using computed signals in the component that wants to use it to something like this:

const someArray: Signal<number[]> = this.store.selectSignal(Selectors.SelectArray)
const first: Signal<number> = computed(() => someArray()[0]);
const last: Signal<number> = computed(() => someArray()[state.someArray.length-1]);
const lastMinusFirst: Signal<number> = computed(() => last() - first());

Or even using signals effects:

const first = 0;
const last = 0;
const lastMinusFirst = 0;

const someArray: Signal<number[]> = this.store.selectSignal(Selectors.SelectArray)

constructor() {
  effect(() => {
    if(someArray().length) {
      this.first = someArray()[0];
      this.last = someArray()[someArray().length - 1];
      this.lastMinusFirst = this.last - this.first;
    }
  });
}

What is the intended way of doing it? Are computed signals more efficient as they mention lazy evaluation and memoized?

sili3011
  • 9
  • 2
  • more efficient - what does that mean ? memory, number of characters in code, speed, storage ? Change your question to "How do I use it" and dont put qualifiers such as better, or efficient, – Rohit Gupta Aug 13 '23 at 03:54
  • What i meant to ask with that part of the question was: are computed signals more performant through the implementation of lazy evaluation nad memoization on their side in comparison to doing the computing part in the ngrx selector? Which in return would be an argument for choosing it over the other one. – sili3011 Aug 18 '23 at 10:18

1 Answers1

0

computed() is better than a selector, because

  1. Its dependencies are dynamic [1];
  2. Resulted signal can be used in the template directly and will take care of the change detection without |async or dirty checking;
  3. Dependencies are recursive - if inside computed() you call some function, that also uses signals, then the resulting signal will be updated when a signal in that function is updated. And this can happen somewhere deep in the stack, as long as it happens synchronously [2]. It allows to create very flexible and powerful things - derived signals, composed of derived signals.

Meanwhile, NgRx is working on integration with Angular Signals:


[1], [2] - You can read more about this topic in my free article: Dependency Graph in Angular Signals

OZ_
  • 12,492
  • 7
  • 50
  • 68