Component Communication in Angular (Parent to Child & Child to Parent)
Tags: angular, beginners, components, programming
Published: 2022-01-15 19:18:05

Today we will learn one of the most important topic in Angular - how to communicate between two components when they have a parent child relationship. 
🔴 **Prerequisite** 🔴
You need to know (if not please follow the link associated)-
🔵 What is a [component](https://dev.to/anubhab5/understanding-angular-component-2bpa) in Angular
🔵 How to create a [component](https://dev.to/anubhab5/creating-angular-component-129e) in Angular

Before we begin we need to understand what is the meaning of parent-child relation. Suppose you have a component called `P`. In the template of the `P` component you write selector of another component say `C`. In this case the component `C` is the child of the `P` component or `P` is the parent of `C`.

So now we know the theory so lets quickly setup our playground. 

We create two components, lets name the parent component as 
`movie-dashboard` or easier way I would say `movie-dashboard` component will act as the parent and `movie-table` (our second component) will act as the child component. 

_The CLI commands_:
`ng g c movie-dashboard`
`ng g c movie-table`
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/31n71uf6n8bpif5lq3we.PNG)
_Project Folder Structure_:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gt1yd9zwpl1qs6m3ofny.PNG)
Parent marked with yellow arrow 🟡
Child marked with green arrow 🟢

In the `app.component.html` we paste in the below code -
```
<app-movie-dashboard></app-movie-dashboard>
```
In the `movie-dashboard.component.html` file lets paste in the below code -
```
<p>movie-dashboard works!</p>
<app-movie-table></app-movie-table>
```
Now if you start the application you should see the following output in the browser's localhost:4200
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5c73804uy6rj7yuxlm6i.PNG)
So now our playground is ready. 

---

❔❔❔ Next big question what are we building ❔❔❔

We will be building a simple flow where the parent component will be holding some movie names/ movie array (I will refer to as movie list from now on...). We will be **passing** the movieList to the child component where we will be displaying the list in a tabular format. 
From the table the user can select a movie by clicking the button (_some user action_)  which will be passed back to the parent (may be for some processing).

So now the context is set. 
Lets see how we can pass data from parent to child. 
We pass data from parent to child using an **Input decorator**.

**Note**:
_**Decorator**_ we already have come across when we defined a component, directive, pipe, module remember??? (`@Component`, `@Directive`, `@Pipe`, `@NgModule`)

All the above decorators are placed on the top of a class. They are also called `Class Decorator`.

Input decorator is a property decorator. What does that mean???
What ever variables you create directly inside a class (not inside a method) are all properties.
And this Input decorator can be put only on the top of a property. So that is the reason it is called Property decorator (and a decorator always starts with @ so `@Input`)
Once you put a decorator it gets some special power like a super hero.
So where should we put this decorator. Easy way I will tell you which will always stick to your mind -

Which ever component will **receive** the data should have the property decorated with `@Input`. So in our case the `movie-table` component will receive the data. So we need to create a property and mark it with the decorator by now you know which decorator we will use.
So lets open the `movie-table.component.ts` file and paste in the below code -
```
  @Input()
  movieList: Array<string> = [];
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw4jekd8o0wghfg24p2v.PNG)
You can see line number 11 is the `movieList` property. We have put the `@Input()` on the line number 10. 
Although you can put in front of the property as well like below -
```
  @Input() movieList: Array<string> = [];
```
So once we use this decorator on a property the property is able to hold the data we pass from parent.

By now we got some one who will hold the data in the child. But how to pass the data from parent. For that lets go to the `movie-dashboard.component.ts` file and paste in the below code -

```
  myFavoriteMovies = [ 'Encanto', 
'Spider-Man: No Way Home', 
"Harry Potter and the Sorcerer's Stone" ];
```
and now come to the corresponding template file the `movie-dashboard.component.html` and paste in the below code (by removing the old code present) -
```
<p>movie-dashboard works!</p>
<app-movie-table [movieList]="myFavoriteMovies"></app-movie-table>
```
Here we have 2 points to note-
1️⃣ The input decorator property we created in the child component is placed inside the square bracket []. Here `movieList` is present inside the square bracket.
2️⃣ The data which we want to pass to the child should be assigned to the above property. We use equal operator and the variable which contains the data. Here `myFavoriteMovies` property contains the data which we have assigned.

That's it now its ready & we learnt how to pass the data from parent to child. 
But wait I need to show it to you also right?
So for that lets paste in the below code in the `movie-table.component.html` 

```
<table>
    <tr>
      <th>Movie Name</th>
      <th></th>
    </tr>
    <tr *ngFor="let movie of movieList">
      <td>{{movie}}</td>
      <td><input type="button" value="Select"></td>
    </tr>
</table>
```
You will see the output as -
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ljqbupklkfw0kmidmnu.PNG)
Wow! We are receiving the data in the child component.
As I said earlier `movieList` property will receive the data from the parent. Since we are passing an array we are just looping through it using [ngFor](https://dev.to/anubhab5/understanding-built-in-angular-directives-part-5-gli) (If you are not aware of please have a look).

Our First step is done - Passing data from parent to child.
Now comes the second part. The user clicks the select button and the selected movie will be passed to the parent component.

For that we will learn yet another new property decorator the
Output decorator.

So lets paste in the below code in the `movie-table.component.ts`

```
  @Output()
  movieSelectedEventEmitter =  new EventEmitter();
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ri5leqwthc8pmxqwxk4k.PNG)
So here we are adding a property `movieSelectedEventEmitter` and decorating with Output decorator. And now what is the remaining part?
When ever the user clicks a button it actually raises an event which will emitted back to the parent. We are actually creating an object of it. So the property becomes super powerful (like our action hero) and can emit/ send the data to the parent component.

But we also need to capture the click event when the user clicks the button. So lets create a method which will be called when the user clicks the button.

```
  movieSelected(selectedMovie: string) { }
```
Nothing in the body yet. We will fill it soon!

In the corresponding template file lets paste the below code 
```
 <td><input type="button" value="Select" 
(click)="movieSelected(movie)"></td>
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo0kn4s15rb3rmv638cj.PNG)
All events we write inside a round bracket `()`. 
Here `click` is an inbuilt event.
And once that event is fired/ triggered the function we pass just after the equal operator will be called.
Now lets come back to the method which we just now created. And paste in the below code -

```
this.movieSelectedEventEmitter.emit(selectedMovie);
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xejffysooao85ls3d1l.PNG)
So what are we doing?
On the Output property we created we are calling the emit (remember we assigned an EventEmitter object) and passing the data, in this case the selected movie name.

But the job is still half done. In order to get the data in the parent we need to add few extra lines of code.
So lets open the `movie-dashboard.component.html` file and paste in the below code (and you can remove the old one)-
```
<p>movie-dashboard works!</p>
<app-movie-table 
(movieSelectedEventEmitter)="selectedMovieToWatch($event)" 
[movieList]="myFavoriteMovies">
</app-movie-table>
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/964ro26hyvk1t2md0age.PNG)

Here we are using the event emitter we created `movieSelectedEventEmitter` (or the Output property inside a round bracket since its an event, same formula as the click we used few steps back) and assigning it to a method which will be called when the event is triggered (exactly same concept/ way as the click event, the only difference is click is an inbuilt one and this is a custom/ user-defined one)

So lets define the `selectedMovieToWatch` method.
In the movie-dashboard.component file lets paste the below code - 
```
  selectedMovieToWatch(data: string) {
    debugger;
    alert(data);
  }
```
Here data will receive the value which we passed from the child.
That's it. Now lets look at the output -
I clicked the second item (trust me)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/od2bhgxw3709d0lqyr6q.PNG)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1vmsdla6jr0hw81hyht.PNG)

So this brings to the end!!! I know it was a long post.

## Highlights
`Input`
1️⃣ Need to decorate a property in the **child component** as @Input()
```
  @Input()
  movieList: Array<string> = [];
```
2️⃣ In the Parent component where the child selector is used need to add the same input property in Square Bracket [] and assign the value to be passed
`[movieList]="myFavoriteMovies"`

`Output`
1️⃣ Need to mark a property in the child component with the Output decorator and assign an EventEmitter Object
```
  @Output()
  movieSelectedEventEmitter = new EventEmitter();
```
2️⃣ In the parent we need to add the event and assign to a method
`(movieSelectedEventEmitter)="selectedMovieToWatch($event)" `


Hope you enjoyed reading the post

If you liked it please do _like_ ❤️ _share_ 💞 and _comment_ 🧡.

Coming up more topics on Angular.
So stay tuned.

I will be [tweeting](https://twitter.com/Anubhab_0905) more on `Angular` `JavaScript` `TypeScript` `CSS`
So hope to see you there too 😃

**Cheers**!!!
_Happy Coding_