How to detect changes on an @Input with Angular.

Bradley
DVT Software Engineering
3 min readAug 22, 2022

One of the most frustrating things you’ll encounter when writing Angular code is how to trickle down (pass down information rather) from the parent component down to the child component that you re-use in various components.

Well, that’s the problem I found myself in the first few weeks of working with Angular. From my previous React/React Native background, this was such an easy thing to do. It was a shocking surprise when I read a little more into the workings of “the how to” achieve this in angular.

Essentially, the solution boils down to two approaches:

  1. The easier route (Letting Angular do the work for you) and
  2. The more “in control” approach where you define a single getter and setter on an input property. Not only can we use getters and setters to achieve this, but we can define a private property and use getters and setters on them, using getters to retrieve these properties (say to display them in a view).

Step 1: The Easy approach

Here’s how we can write a component to use ngOnchanges to detect changes on an input.

Let’s say you’re a huge music fanatic. You live and breathe music and want to detect and log changes when there’s a music change in your player component; how do you go about this? Well, hook to the lifecycle — use one of Angular’s lifecycle hooks.

ngOnChanges() is one of the many angular lifecycle hook methods. This one, in particular, responds when a data-bound input property has a change invoked. This method receives SimpleChanges object.

SimpleChanges object consists of current and previous property values, which we can use to check if any changes have been detected by our @Input decorator.

Let’s see how we can listen to changes on an Input using this lifecycle method.

SelectedMusicPlayerComponent.component.ts

Here we have a player @Input of type Player. On line 7, we check if player firstChange is false, that is, if the player input has received a change. If that is the case, then proceed to log the currentValue or new recently updated player data. This is achieved by using the changes object, which contains the current and previous values of player.

Step 2 : Self-defined approach: Setters and Getters

Here our SelectedMusicPlayerComponent has an @Input decorator. We set a setter “player” function to this Input decorator to detect changes to the player function; essentially, whenever the player property changes, the set will be called. And we’re done! Or, are we? No, we’re not.

This set on its own cannot work. It only allows us to display the detected change on the console, or in this case, “value” logged. So to display the property onto our template (myComponent.html), we need to define a private property.

Private Property and getter

We can define a private property to hide or display the detected change onto our template HTML when needed like so:

Above, we introduced a get. This essentially gets the data and returns it, unlike a set that allows us to initialise our property, in this case, our “_selectedPlayer” to a detected change (value).

Fun fact for the fun code lovers. set will always be invoked first before ngOnchanges lifecycle hook because it is plain typescript/javascript.

I hope this short post has at least piqued your interest in exploring the many different ways we could listen to change bound to an input decorator and proceed with writing amazing code.

--

--

Bradley
DVT Software Engineering

Mobile Application,Angular Front-End developer & Website Developer