Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 15, 2022 07:18 pm GMT

Component Communication (Parent to Child & Child to Parent)

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 in Angular
How to create a component 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
Project Folder Structure:
Image description
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
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
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 = [    {      movieName: 'Encanto',      genre: 'Animation'    },    {      movieName: 'Spider-Man: No Way Home',      genre: 'Action'    },    {      movieName: "Harry Potter and the Sorcerer's Stone",      genre: 'Fantasy'    }  ];

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
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 (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
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
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
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

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
Image description

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 more on Angular JavaScript TypeScript CSS
So hope to see you there too

Cheers!!!
Happy Coding


Original Link: https://dev.to/this-is-angular/component-communication-parent-to-child-child-to-parent-5800

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To