DEV Community

Cover image for You may not need ngOnChanges
Hank Chiu
Hank Chiu

Posted on β€’ Edited on

3 1

You may not need ngOnChanges

"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
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

2) By naive setter

class CounterComponent {
  @Input()
  get count(): number {
    return this._count;
  }

  set count(value) {
    this._count = value;
    // do something
  }

  private _count: number;
}
Enter fullscreen mode Exit fullscreen mode

3) By Subjectize

class CounterComponent implements OnInit {
  @Input()
  count: number;

  @Subjectize("count")
  count$ = new ReplaySubject(1);

  ngOnInit() {
    this.count$.subscribe(() => {
      // do something
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

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!

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

Sentry image

See why 4M developers consider Sentry, β€œnot bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

πŸ‘‹ Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay