Property Watch Decorator
@OnChange
decorator that can be easily used to listen to changes of class properties.
This package provides a talk at ng-conf 2019 about why this package is useful and how I implement this package.
I have aInstall
npm install property-watch-decorator
Example 1
class PersonComponent {
// Parameter value is inferred as any
// Parameter change is optional, and inferred as SimpleChange<any>
@OnChange(function(value, change) {
console.log(`name is changed from ${change.previousValue} to ${value}`);
})
name: string;
}
Example 2, use generics, better typing
class PersonComponent {
// Parameter value is inferred as string
// Parameter change is optional, and inferred as SimpleChange<string>
@OnChange<string>(function(value, change) {
console.log(`name is changed from ${change.previousValue} to ${value}`);
})
name: string;
}
this
if you want to access other member of the class (just for better IDE integration)
Example 3, type class PersonComponent {
@OnChange<string>(function(this: PersonComponent, value, change) {
console.log(`name is changed from ${change.previousValue} to ${value}`);
console.log(`At the moment, age is ${this.age}`)
})
name: string;
age: number;
}
this
as in example 3)
Example 4, using class method reference for onChange (No need to type class PersonComponent {
@OnChange<string>('onNameChange')
name: string;
age: number;
onNameChange(value, change) {
console.log(`name is changed from ${change.previousValue} to ${value}`);
console.log(`At the moment, age is ${this.age}`);
}
}
Important notes:
PITFALL 1
Arrow function should be avoided as this would make the function lose context. In this case, this
would NOT refer to class instance but undefined
For example: it is WRONG to use this way
class MyComponent {
@OnChange(value => {
console.log(`property1 is changed to ${value}`);
console.log(this.property1) // "this" would refer to undefined, cannot access "property1" of undefined
})
property1: any;
}
Correct way
Change arrow function to es5 function:
class MyComponent {
@OnChange(function(value) {
console.log(`property1 is changed to ${value}`);
console.log(this.property1) // "this" would refer to component instance
})
property1: any;
}
PITFALL 2
Callback function CANNOT be referred to class method, this would also cause this
to be undefined
For example:
class MyComponent {
@OnChange(this.someFunction) // "this" would refer to undefined, cannot access "someFunction" of undefined
property1: any;
someFunction(value) {
console.log(`property1 is changed to ${value}`);
console.log(this.property1)
}
}
Correct way 1
class MyComponent {
@OnChange('someFunction')
property1;
someFunction(value) {
console.log(`property1 is changed to ${value}`);
}
}
Correct way 2
class MyComponent {
@OnChange(someFunction)
property1;
}
function someFunction(value) {
console.log(`property1 is changed to ${value}`);
}