- July 25, 2019
- Posted by: iSummation Team
- Category: MEAN Stack

Welcome beginners, yes this is more or less for the developers who just started their journey as Angular 2+ developer or want to learn Angular 2+. Most of the new Angular Developers face problems in sharing the data between the components. Also if you are applying as fresher or junior level then chances are high, that it is one of the question you may be asked during your interview. I have tried to make it as simple as it can be.
We will cover five different methods for sharing the data between the Angular components:
- Using Input decorator
- Using Output decorator
- Using services
- Using ViewChild
- Using route parameters
On most if the places you will see commonly the first four methods to pass data between the components. But believe me sharing data using DOM is also important some scenarios(we will discuss in later section).
OK, so let’s get started.
Now there are scenarios where you have to apply different approach. According to those scenarios, lets start discussing from the top:
Using Input decorator
This is the most common and very useful way to share data between the components. Suppose when you have parent-child relationship between the two components and you want to pass the data from parent to child, then is where Input decorator comes into the picture.
Child component code
1 2 3 4 5 6 7 8 9 10 |
@Component({ selector: "app-child", template: "{{childName}}", }) export class ChildComponent{ @Input() childName: string = ''; } |
In the above code I have declare the childName property using the Input decorator. You can use this as a global variable for this ChildComponent class.
Parent component code
1 2 3 4 5 6 7 8 |
@Component({ selector: "app-parent", template: "<app-child [childName]="'My first child'"><app-child>", }) export class ParentComponent{} |
Now in the parent component I have used the ChildComponent selector to bind the child component in the parent and using [] in the app-child tag I can pass the the data to the child component.
So simple isn’t it.
Using the Output decorator
Now you are wondering I want to pass the data to the parent from the child, so how can I do so.
Just wait, I will show you how simple is that. Let’s modify the child component first for our need.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@Component({ selector: "app-child", template: "{{childName}}", }) export class ChildComponent{ @Input() childName: string = ''; @Output() favGame: EventEmitter<any> = new EventEmitter<any>(); constructor(){ this.favGame.emit('PubG') } } |
In the above code I have declared the event emitter using Output decorator and in the constructor I am emitting an event which we can listen in our parent component. See below,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Component({ selector: "app-parent", template: "<app-child (favGame)="onGameChange($event)" [childName]="'My first child'"><app-child>", }) export class ParentComponent{ onGameChange(event){ console.log(event); } } |
In the above code whenever we emit the event from the child component then then onGameChange method will be called. In this way you can easily pass the data from child to parent.
Using services
Now suppose you have two child components as siblings and you want to pass data from one sibling to another. Then the combination of above two approach can be used like emitting the data from one child component to parent and passing that data to another child. That is good when you do not have many nested components, otherwise the number of event emitters may increase.
This can be solved using angular services and RxJS Observables and Subject. I will show you to code a message bus in Angular project which can deliver data between any component.
Message service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Injectable() export class MessageService { private subject = new Subject<any>(); message = this.subject.asObservable(); send(data: any) { this.subject.next(data); } constructor() {} } |
First Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Component({ selector: "app-first", template: "<div>My first component</div>", }) export class FirstComponent{ constructor(private messageService: MessageService){} this.messageService.send("This message is from First Component"); } |
Second Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@Component({ selector: "app-second", template: "<div>My second component</div>", }) export class SecondComponent{ constructor(private messageService: MessageService){} this.messageService.message.subscribe((data: string) => { console.log(data); }) } |
So using the above approach you can observe the to multiple places or you can send the flag that this data is for which component.
Using ViewChild
Using this method you can directly access the child component public properties. This method is also useful when you want access the child component properties.
ViewChild is query selector which selects the element from the template using selector passed in the query. See below:
Child component code
1 2 3 4 5 6 7 8 9 10 11 |
@Component({ selector: "app-child", template: "<div>I am child component.</div>", }) export class ChildComponent{ name: string = 'Superman'; } |
Parent component code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import {ChildComponent} from "child.component.ts"; @Component({ selector: "app-parent", template: "<div>I am parent component.</div> <app-child></app-child>", }) export class ParentComponent{ @ViewChild(ChildComponent, { static: false }) child: ChildComponent; ngAfterViewInit(){ const childName: string = this.child.childName; console.log(childName); } |
So in this way you can query the view and access the child properties. But always remember to use the AfterViewInit lifecycle hook with ViewChild decorator as query is made after the view is initialised.
Using route parameters
This is again the common approach to edit or access the data based on the IDs. Suppose I have a course which have 10 chapters. Now I have a list of all the chapters on the parent component and I want to edit one chapter.
So using this approach when you navigate to different router using the chapter ID, you can catch that ID from the child route using the ActivatedRoute Angular core API.
Conclusion
So that’s all about sharing the data between the Angular components. Always master these tools to make Modular Angular Applications.
“Always share good thoughts, It will come back to you..!”