0

In Vue.js, the watch function gets the new and old watched value passed as arguments, which is really helpful in case the differences matter, or when I want to release the previous allocated resource.

Now in Angular 16, we finally have signal, computed, and effect. effect() seems to be the equivalent of the watch in Vue.js. But is it there also possible to get access to the old value?

The Angular API docs only mention onCleanup. As effect does not operate on an expression as in Vue, it might not be possible to store a previous value in a generic way.

Is there a workaround?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Peter T.
  • 2,927
  • 5
  • 33
  • 40
  • 1
    In Angular you have full access to rxjs operators. I imagine you can use [pairwise](https://rxjs.dev/api/operators/pairwise) with all the changes related to observables (forms, httpClient, ..) – Eliseo May 08 '23 at 13:38

3 Answers3

1

Angular's effect doesn't allow to listen for a particular property change.

Like @Eliseo said, you can achieve that by leveraging rxjs:

toObservable(mySignal)
   .pipe(
      pairwise(), 
      map(([oldValue, newValue]) => { ... })
    )
Matthieu Riegler
  • 31,918
  • 20
  • 95
  • 134
1

Effect does not give an old value, as signals only store the current value. Angular shipped an rxjs interop package, @angular/core/rxjs-interop, which help you for this kind of usecase. You can use the toObservable function as follows to achieve what you want:

/**
  * Signal version of count
  */
count = signal(0);

/**
  * Straight conversion to observable
  */
count$ = toObservable(this.count);

/**
  * Pairwise conversion to achieve old/new functionality
  */
countPrevAndCurr$ = this.count$.pipe(
  pairwise(),
  map(([oldVal, newVal]) => {
    console.log('Old Value (Observable): ', oldVal);
    console.log('New Value (Observable): ', newVal);
    return { old: oldVal, new: newVal };
  })
);

Here is a StackBlitz showing the functionality in action.

Note: At the time of writing this answer both the Angular Signals and Rxjs Interop packages were in developer preview so this is potentially subject to change.

John Woodruff
  • 1,608
  • 16
  • 29
0

` public historicValue : any = [] public messageAlert = false;

public countEffect = effect(()=>{    
 this.historicValue.unshift(this.counterPrueba());
  if(this.historicValue.length > 1){
    this.alert = `El contador ${this.historicValue[1]} se ha modificado a  ${this.counterPrueba()}`
    this.messageAlert = true;
  } 

});`

alex213
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 03 '23 at 12:27