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?
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.