How to listen for value changes from class property TypeScript - Angular How to listen for value changes from class property TypeScript - Angular angular angular

How to listen for value changes from class property TypeScript - Angular


You can still check component's field members value change by KeyValueDiffers via DoCheck lifehook.

import { DoCheck, KeyValueDiffers, KeyValueDiffer } from '@angular/core';differ: KeyValueDiffer<string, any>;constructor(private differs: KeyValueDiffers) {  this.differ = this.differs.find({}).create();}ngDoCheck() {  const change = this.differ.diff(this);  if (change) {    change.forEachChangedItem(item => {      console.log('item changed', item);    });  }}

see demo.


I think the nicest solution to your issue is to use a decorator that replaces the original field with a property automatically, then on the setter you can create a SimpleChanges object similar to the one created by angular in order to use the same notification callback as for angular (alternatively you could create a different interface for these notifications, but the same principle applies)

import { OnChanges, SimpleChanges, DoCheck, SimpleChange } from '@angular/core';function Watch() : PropertyDecorator & MethodDecorator{    function isOnChanges(val: OnChanges): val is OnChanges{        return !!(val as OnChanges).ngOnChanges    }    return (target : any, key: string | symbol, propDesc?: PropertyDescriptor) => {        let privateKey = "_" + key.toString();        let isNotFirstChangePrivateKey = "_" + key.toString() + 'IsNotFirstChange';        propDesc = propDesc || {            configurable: true,            enumerable: true,        };        propDesc.get = propDesc.get || (function (this: any) { return this[privateKey] });        const originalSetter = propDesc.set || (function (this: any, val: any) { this[privateKey] = val });        propDesc.set = function (this: any, val: any) {            let oldValue = this[key];            if(val != oldValue) {                originalSetter.call(this, val);                let isNotFirstChange = this[isNotFirstChangePrivateKey];                this[isNotFirstChangePrivateKey] = true;                if(isOnChanges(this)) {                    var changes: SimpleChanges = {                        [key]: new SimpleChange(oldValue, val, !isNotFirstChange)                    }                    this.ngOnChanges(changes);                }            }        }        return propDesc;    }}// Usageexport class MyClass implements OnChanges {    //Properties what I want to track !    @Watch()    myProperty_1: boolean  =  true    @Watch()    myProperty_2 =  ['A', 'B', 'C'];    @Watch()    myProperty_3 = {};    constructor() { }    ngOnChanges(changes: SimpleChanges) {        console.log(changes);    }}var myInatsnce = new MyClass(); // outputs original field setting with firstChange == truemyInatsnce.myProperty_2 = ["F"]; // will be notified on subsequent changes with firstChange == false


as said you can use

public set myProperty_2(value: type): void { if(value) {  //doMyCheck } this._myProperty_2 = value;}

and then if you need to retrieve it

public get myProperty_2(): type {  return this._myProperty_2;}

in that way you can do all the checks that you want while setting/ getting your variables such this methods will fire every time you set/get the myProperty_2 property.

small demo: https://stackblitz.com/edit/angular-n72qlu