In this tutorial, you will learn how data can be passed from one component to another.
The best way to understand this is via a demo
- Setup the Parent and Child Components
- Pass Variable from Parent to Child
- Pass Variable from Child to Parent
- How it Works
1. Setup Parent and Child Components
Step 1: Create two components: Parent and Child. We would like to nest the within the parent component. Then we also pass some variables from the parent to the child
Step 2: Add routing as well as link so that we can see the Parent component by clicking a link in the app component
Step 3: Create a string array field in the parent component. I called it books. Assign it a list of string. Like so:
this.books = ['Harry Porter', 'Oliver Twist', 'Animal Farm', 'Othello'];
This is added in the ngOnInit() method. And of course, remember to define the field.
Step 4: Add another variable. I call it papa, and assign it a value ‘Daddy’.
this.papa = 'Daddy';
Step 5: Nest the child component inside the parent component template. So the parent component template is now:
<p>parent works!</p> <div class="container"> <app-child></app-child> </div>
Launch the application and check that it works. If so then, great!
2. Pass Variable from Parent to Child
First, we need to prepare the child component to receive variable from the parent. To do this, we use the @Input annotation.
When you annotate a variable with @Input annotation, you tell Angular that the variable can receive data from a parent component. So take the steps below:
Step 1: Create two variables in the child component and annotate them with @Input.
@Input() recievedBook: string; @Input() myDadName: string;
Step 2: Render this properties on the child template. I use the code below, but you can modify it. Actual values will come from the parent component.
<h3>I recieved the book {{recievedBook}}</h3> <p>Thank you {{myDadName}}</p>
Step 4: Now adjust the markup for displaying the child component. We’ll loop through all the books in the parent component and for each book, we display the child component. See code below:
<app-child *ngFor="let book of books" [recievedBook]="book" [myDadName]="papa"> </app-child>
Now if you run the code, the output would be as shown below:
3. Pass Value from Child to Parent
The communication from child to parent is achieved via EventEmitter. How it works is this: a property(variable) in the child component is annotated is marked as an EventEmitter. So when the value changes, it emits and event. Then the parent listens to this event. Moreover, this variable is annotated with the @Output annotation.
We’ll demonstrate this using a polls example. Users are able to respond yes or no in the poll on the child component. Then the totals are collected in the parent component.
We call the child component voter and the parent component, counter.
Step 1: Create the two components: voter and counter. Also add routing.
The voter(child) component ts file is given below
export class VoterComponent { @Input() voter: string; @Output() voted = new EventEmitter<boolean>(); didVote = false; vote(userResponse: boolean) { this.voted.emit(userResponse); this.didVote = true; } }
The voter(child) HTML template is shown below as well
<h3> Vote by {{voter}}</h3> <button (click)="vote(true)" [disabled]="didVote" class="btn btn-outline-success">Yes</button> <button (click)="vote(false)" [disabled]="didVote" class="btn btn-outline-danger">No</button> <br>
How it works – Child Component
The child component has two buttons, Yes and No. When the user clicks on the button, the method vote() is called. In this method, property event emitter, voted emits and event with the user’s response as payload(or argument). This event is to be picked up by the parent component
How it works – Parent Component
The ts code for the counter(parent) component is given below:
export class CounterComponent implements OnInit{ respondents: string[]; yes: number; no: number; ngOnInit(): void { this.respondents = ['Ndubuisi', 'Osondu', 'Adaku', 'Ijeoma']; this.yes = 0; this.no = 0; } onVoted(response: boolean) { response ? this.yes++ : this.no++; } }
The HTML template is given below:
<div class="container"> <h2>Do you think climate change is a crisis?</h2> <h3>Yes: {{yes}}, No {{no}}</h3> <hr> <app-voter *ngFor="let respondent of respondents " [voter]="respondent" (voted)="onVoted($event)"> </app-voter> </div>
In the parent component, the event handler onVoted() responds to the child event payload variable, $event. So the parent component listens to changes in the voted variable. This change is communicated to the parent using the userResponse parameter of the emit() static method of the voted property.
I’ll recommend you take some time to digest this and also watch the video for clarification.
The output is shown below:
[…] Angular 10 – Component Interaction […]
[…] Once the player has gotten to the last question, we simply end the quiz and show the score. To do this we need to compare the current index with the total questions. However, the total questions is in the child component. So we need to receive it in the parent component. Again, we use EventEmitter. […]