Angular child-to-parent communication with the @ViewChild() decorator mostly involves configuring the parent component to pay attention to one or more child component properties.
In the article: “Angular Parent to Child Communication with @Input()”, I covered the process of passing data from a parent component to a child component. I this article, I will cover one of two possible approaches to Angular child-to-parent communication. This particular approach takes advantage of the ViewChild decorator, and the syntax is fairly straightforward and easy to understand.
When I first looked into Angular child-to-parent communication, I assumed that it might be as simple as reversing the steps taken with the @ViewChild() decorator, but this was not quite the case. Leveraging the @ViewChild() decorator differs from the @Input() approach because not only are we accomplishing the opposite task, but the overall steps and methods of communication lack resemblance to the @Input() approach. Also, the communication mechanism requires a bit of event handling.
First, we import the child component from the parent component. The @ViewChild decorator is then used to set up a new property on the parent component, which provides the data connection from the child component. Next, we tap into the ngAfterViewInit component lifecycle hook, thereby making the live connection between one or more parent component properties and the respective child component properties. The steps required in the child component do not require much special attention, so it’s safe to say that Angular child-to-parent communication with the @ViewChild() decorator mostly involves configuring the parent component to pay attention to one or more child component properties.
Full Working Example Code
You can clone the full working example code here: github.com/kevinchisholm/video-code-examples/tree/master/angular/components/ViewChild
- Go to this folder in your terminal: angular/components/ViewChild
- Follow the directions in the readme
The Parent Component & @ViewChild() – Example # 1
Example # 1 contains all of the code for the parent component. On line #s 2 and 3, we import the children components: Child1Component and Child2Component. Now this is a bit of a departure in that we normally import services in an Angular component, but in this case, we need access to the instances of the children components.
Next, on line #s 10 and 11, we use the @ViewChild decorator to create properties that represent instances of each child component class. The syntax is a bit odd, but just note that while we reference the child component class twice (e.g. Child1Component), what we wind up with is a new property (e.g. child1).
On line #s 13 and 18 we create the properties userInfo1 and userInfo2, and we do this to set up objects that can be used to take in data from the child components. Finally, on line # 23, we tap into the ngAfterViewInit component lifecycle hook, and what we are saying here is: “after the PARENT component has completely initialized, please get the child1.userInfo and child2.userInfo values and assign them to this.userInfo1 and this.userInfo2“.
So, as I mentioned above, most of the action is now over. The real “wiring-up” steps take place in the parent component. The methodology here is that we are listening for changes to some data points on the child components.
The Parent Component’s Template – Example # 2
In Example # 2 we have the parent component’s template, and on line #s 3, 4, 7 and 8 we have bindings for the child component properties that we wired-up on the parent component. These are the places in the UI that the child component data will render (and automatically update whenever that data changes in the child). And then, on line #s 10 and 11, we have the child1 and child2 elements. Nothing too special there, since most of the setup work was done in the parent component.
The Child 1 & Child 2 Components – Example # 3
Example # 3 has the code for both the Child 1 and Child 2 components. The code is virtually identical, so I won’t spend any time comparing the two, but what I wanted to point out here is that there is not too much to point out : – ). The code you see in the Child 1 and Child 2 components pretty much looks like what you would expect from any Angular component. Just note, though, that in each child component, we create a userInfo object which is used to set up the data bindings.
The Child 1 & Child 2 Component Templates – Example # 4
And pretty much the same situation here; the Child 1 and Child 2 component templates are virtually identical. We have HTML text inputs that allow the user to enter some text, and whenever the user adds or edits that text, the respective properties of the userInfo object are updated and that data flows up to the parent component.
If you have the time, I recommend cloning the github repo at the top of this page and running the example code locally, because while (I hope) the code examples are straightforward, it might be helpful to actually see the code in action. When you do, you’ll see that as you type in each child component text input, that data is reflected in the parent component. This makes it a bit easier to understand how the data flows up from the child components to the parent component.