Angular: Component interaction with @Input, @Output and EventEmitter
Angular is all about components that have to interact with one another. How can you change data of a component when using another one? In this article, I will explain how we can easily pass data through parent and child components using the @Input, @Output decorators and the EventEmitter.
A quick introduction
First, let’s give some explanation about those decorators. We have the @Input decorator. @Input links a property of a component (which is generally the child component) with a value that was given by another component (the parent).
On the other side, the @Output decorator is used to link a property of a child component and emit it through the event emitter. So the parent component can call the property and get the data emitted from it.
To summarise: @Input is used to pass data from parent to child and the opposite, @Output, can be used when you want to pass data from the child to the parent (which can also be done with observables or simple functions).
Let’s put this in practice!
@Input decorator
Let’s say that we have a component named ‘parentComponent’ and another component named ‘childComponent’. The parent wants to send a simple message that will be caught and displayed by the child.
So first, let’s create a simple string variable in our parent.component.ts file. It will contain the message that we want to give to our child.
Then, in the child.component.ts file, we will define a simple variable ‘receivedParentMessage’ that will be the displayed message from the parent inside the child. Add the @Input decorator in front of the variable like this:
Now that we have our input the parent is able to know where it can give its message. We simply need to pass the parent message when we are calling the child.
Notice that ‘receivedParentMessage’ is between square brackets. It is a template expression that you have to use to bind the content of those brackets to the @input decorator.
Now you can display the ‘receivedParentMessage’ into your child.component.html file the way you want.
@Output decorator & EventEmitter
Let’s focus on the @Output. We now want our parent to get some data coming from our child. Basically, the child has to emit his message and the parent will receive it.
We can simply start by defining another string variable which represents the message given by the child inside our parent.component.ts. Then, in the child component we define our message property that will be sent. This time, we add the @Output decorator and we make it a new EventEmitter (make sure that you have imported the EventEmitter from Angular core!).
As you can see, when creating a new EventEmitter, we have to specify the type of the element that will be emitted. In our case, we put string.
Now, we can emit our message so that our parent can receive it. Let’s create a simple function that can be called by clicking on a button for example.
That is all on the child’s side. We have to tell our parent to point our emitter and catch the payload of it (which represents the element emitted). Just add a function in your parent.component.ts file that will get the message and pass it to our parent variable. Then you can add the following code into your html.
Here’s what we have done:
- In the parent.component.ts: We created a function that will receive the message caught by the parent that comes from the emitter and pass the value of it to our receivedChildMessage variable.
- In the parent.component.html: By using the parentheses, we targeted our emitter and then we put the payload (by writing $event) of it inside our getMessage function.
And that is it! You can display the messages from the parent and the child as you wish. I let you an easy demo with some buttons so you can play around :)