Parent-Child component: Meaning
An angular application is made up of components and often components are nested inside one-another. Example, suppose you have a table of rows on a page. In this simple structure we can have 2 components:
A table component which represents the entire table and a component which represents a single row of the table. If we have this kind of structure, then table will contain row component and thus table component will be the Parent component and row component will be the Child component.
In simple words, when one component contains another component, then the components are said to be nested. When the components are nested, the components which contains other component is called Parent component and the contained component is called Child component.
When there are nested component, it becomes necessary to share data between components. Often you need to supply some values from parent to child component and vice-versa. This is also called parent-child component communication or interaction.
This post will explain a couple of methods to transfer data from parent to child component.
How to pass data from Parent to Child Component
There are two methods to pass values from parent component to child component, one is using input properties and another is by utilizing a service. Both of these are explained in detail below.
Method 1: Using Input properties
An input property is a field(or member) of the component class which is annotated with @Input()
decorator. Its main purpose is to receive a value sent from the parent component.
Example, consider the below component class referred as ChildComponent which has an input property named message
as shown.
import { Component, OnInit, Input } from ‘@angular/core’;
@Component({
selector:’child‘,
templateUrl:’./child.component.html‘,
styleUrls: [‘./child.component.css‘]
})
export class ChildComponent {
@Input() message: string;
}
HTML template for this component is given below. This HTML template displays the value of its property which is an input property.
Message sent from Parent is : {{messageFromParent}}
Now let us define the Parent component for the above component.
import { Component, OnInit } from ‘@angular/core’;
@Component({
selector: ‘parent‘,
templateUrl: ‘./parent.component.html‘,
styleUrls: [‘./parent.component.css‘]
})
export class ParentComponent implements OnInit {
messageToChild: string
ngOnInit() {
this.messageToChild = “How are you?”;
}
}
Parent component has one property which contains the message to be sent to the child or the value which will be sent to the input property of the child.
HTML template of the parent will look like
Notice how the value of input property of child component is set from the parent component. Input property of the child should be enclosed within square brackets and must be on left side while property of the parent will be at the right side.
When this application is deployed and run, it shows the following output on the browser.
Calling child with message
Message sent from Parent is : How are you?
Look, the value sent by parent is successfully received by the child.
Method 2: Using a Service
A service is a special class which is generally used to fetch data from server. It may also be used to share data between components.
A service is not tied to any component or module but it can be used by multiple components. If you are familiar with any programming language that uses classes such as C++, Java or C#, then a service may be compared to a utility class containing static methods which can be used by multiple classes.
A service in angular is annotated with @Injectable
annotation and it is directly injected into a component.
To learn about an angular service in depth, then refer this link.
Below is a service which contains a field to store a string and methods to provide value to this field and to read value of this field.
import { Injectable } from ‘@angular/core’;
private message : string;
}
Have a look at the modified parent and child components. Both parent and child components utilize the same service which is injected into them via their constructors.
Parent calls the setMessage
method of the service to set the message it wants to send to child in the message
field of the service and child calls the readMessage
method of the service to read the value of message
field.
Note that child now does not contain any input property.
Typescript for Parent component
import { Component, OnInit } from ‘@angular/core’;
@Component({
selector: ‘parent‘,
templateUrl: ‘./parent.component.html‘,
styleUrls: [‘./parent.component.css‘]
})
export class ParentComponent {
private service;
// service injected
constructor(codippaService: CodippaService) {
this.service=codippaService;
this.sendMessage();
}
}
Typescript for Child component
import { Component } from ‘@angular/core’;
@Component({
selector:’child‘,
templateUrl:’./child.component.html‘,
styleUrls: [‘./child.component.css‘]
})
export class ChildComponent {
private message:string;
// service injected
}
// call service method to read message
}
Modified HTML template for parent is given below. Parent now simply calls the child component. HTML template for child remains the same as earlier.
Output on the browser is
which is same as earlier.
Calling child with message
Message sent from Parent is : How are you?
Again, the value sent by the parent is successfully received by the child.
Comparing Both Methods
When comparing both the above methods, as which to use when, then there is a simple logic. If the components which want to share data exhibit a parent-child relation, then you should go with method 1, that is, using input properties and not with method 2.
This is because a service is primarily designed to contain methods that are common among components and to perform utility tasks while input properties are mainly designed to receive value from parent components.
Method 2 should be used when there is no parent-child relationship between components sharing data or the components are unrelated to each other. If they possess a relation, then go with input properties.
Also, method 1 can only be used to pass data from parent to child while method 2 can also be used to pass data either way(both from parent to child and from child to parent).