"ngOnChanges" is a lifecycle hook for an Angular component to know when the @Input props are changed. The main drawback of using ngOnChanges is that you have to write much more code to watch a single prop.
Angular team also provides another way to intercept the property changes by setter. If you use the setter technique naively you would find it tediously to write the getter/setter pair and the redundant private variable.
In this article, I would like to share how I improve the setter technique into an npm module - subjectize.
Usage
Say we are building a counter component and would like to do something whenever the count changes. We could have 3 versions of implementation like below(excerpt):
1) By ngOnChanges
class CounterComponent implements OnChanges {
@Input()
count: number;
ngOnChanges(changes: SimpleChanges) {
if (changes.count) {
// do something
}
}
}
2) By naive setter
class CounterComponent {
@Input()
get count(): number {
return this._count;
}
set count(value) {
this._count = value;
// do something
}
private _count: number;
}
3) By Subjectize
class CounterComponent implements OnInit {
@Input()
count: number;
@Subjectize("count")
count$ = new ReplaySubject(1);
ngOnInit() {
this.count$.subscribe(() => {
// do something
});
}
}
They may look fair in such a simple scenario, but things go differently when you have a few Input props to watch. For ngOnChanges, you got lots if logics. For naive setter, you got many boring private variables.
The Subjectize is also a mentally-direct approach: declare a RxJS Subject and subscribe to the Subject for changes, that's it.
The magics
The Subjectize is a TypeScript property decorator. Under the hood, it creates an internal getter/setter for the specified Input prop, just like the naive setter implementation. The Subjectize itself only depends on RxJS, hence you can use it on any ES6 class without Angular. You could also use it for simple state management.
Without saying, there are more things to do to keep the reliabilities. If you are interested, see the source code.
Conclusion
JavaScript getter/setter can be used to watch Input props and subjectize helps you to do that. If you just got fed up with ngOnChanges, give subjectize a try!
Top comments (0)