This page looks best with JavaScript enabled

Share data between components in Angular

 ·  β˜• 6 min read  ·  ✍️ Adesh

Let’s discuss different methods of sharing data in any angular application. We will focus on these methods:

  • @Input: sharing data from parent to child
  • @ViewChild: sharing data from child to parent
  • @Output & EventEmitter: sharing data from child to parent

Method 1: Parent to Child using @Input

This is the most common method of sharing data in Angular application. We will use @Input() decorator to pass data. Create a parent component named app-parent in your app folder. Use this command to generate the component:

Creating parent component

1
ng g c parent
1
2
3
4
5
CREATE src/app/parent/parent.component.css (0 bytes)
CREATE src/app/parent/parent.component.html (25 bytes)
CREATE src/app/parent/parent.component.spec.ts (628 bytes)
CREATE src/app/parent/parent.component.ts (269 bytes)
UPDATE src/app/app.module.ts (683 bytes)

parent.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-parent",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.css"],
})
export class ParentComponent implements OnInit {
  constructor() {}

  ngOnInit() {}
}

Now, let’s create child component named app-child using this command in your app folder.

Creating child component

1
ng g c child

child.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./child.component.css"],
})
export class ChildComponent implements OnInit {
  constructor() {}

  ngOnInit() {}
}

Till now, we have just created our parent and child components in our app. Let' see how to pass data between them. Import the Input decorator in line 1 of child.component.ts file.

1
import { Component, OnInit, Input } from "@angular/core";

Add appChildMessage property with @Input() decorator in same file.

1
@Input() appChildMessage: string;

Add this line to child.component.html file.

1
2
3
4
<p>
  child works!
</p>
<p>Message from parent: {{appChildMessage}}</p>

Now, let’s add these lines to parent component.

parent.component.ts

1
appParentMessage = "This message is from parent";

parent.component.html

1
2
3
4
<p>
  parent works!
</p>
<app-child [appChildMessage]="appParentMessage"></app-child>

So, the complete code would be like this.

parent.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-parent",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.css"],
})
export class ParentComponent implements OnInit {
  constructor() {}

  ngOnInit() {}

  appParentMessage = "This message is from parent";
}

parent.component.html

1
2
3
4
<p>
  parent works!
</p>
<app-child [appChildMessage]="appParentMessage"></app-child>

child.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Component, OnInit, Input } from "@angular/core";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./child.component.css"],
})
export class ChildComponent implements OnInit {
  constructor() {}

  ngOnInit() {}

  @Input() appChildMessage: string;
}

child.component.html

1
2
3
4
<p>
  child works!
</p>
<p>Message from parent: {{appChildMessage}}</p>

passing data from parent to child using @input

Method 2: Child to Parent using @ViewChild()

Using @ViewChild() decorator, we can inject one component to another, giving the parent access to its attributes and functions.

Note: Child won’t be available until after the view has been initialized. So, we need to implement the AfterViewInit lifecycle hook to receive the data from the child.

Let’s look at our parent component code. Write these lines in parent component.

parent.component.ts

1
2
import { Component, ViewChild, AfterViewInit } from "@angular/core";
import { ChildComponent } from "../child/child.component";

Implement the AfterViewInit in component class.

1
export class ParentComponent implements AfterViewInit

Add these lines in component class file.

1
2
3
4
5
6
@ViewChild(ChildComponent) child;
appParentMessage: string;

ngAfterViewInit() {
    this.appParentMessage = this.child.appChildMessage;
  }

Let’s look at complete code.

parent.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { Component, ViewChild, AfterViewInit } from "@angular/core";
import { ChildComponent } from "../child/child.component";

@Component({
  selector: "app-parent",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.css"],
})
export class ParentComponent implements AfterViewInit {
  @ViewChild(ChildComponent) child;
  appParentMessage: string;

  constructor() {}

  ngAfterViewInit() {
    this.appParentMessage = this.child.appChildMessage;
  }
}

parent.component.html

1
2
3
4
5
<p>
  parent works!
</p>
Child Message: {{ appParentMessage }}
<app-child></app-child>

child.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Component, OnInit, Input } from "@angular/core";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./child.component.css"],
})
export class ChildComponent implements OnInit {
  constructor() {}

  ngOnInit() {}

  appChildMessage = "This message is from child to parent";
}

passing data from chid to parent using @viewchild

Method 3: Child to Parent using @Output and EventEmitter

In this method, child component will emit the data, which will be listen by parent component. This ideal condition for this approach is when you want to share some data on some events like button clicks, users and other form related events.

Use this link to read more about @Output and EventEmitter.

We are going to create a function in the parent to receive the message and set it equal to the message variable. Also,Β we are going to declare a messageEvent variable with the Output decorator and set it equal to a new event emitter. Then we will have a function named sendMessage that calls emit on this event with the message we want to send. At the end, we will create a button to trigger this function.

Let’s look at complete code.

parent.compoent.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { Component } from "@angular/core";

@Component({
  selector: "app-parent",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.css"],
})
export class ParentComponent {
  constructor() {}

  appParentMessage: string;

  receiveMessage($event) {
    this.appParentMessage = $event;
  }
}

parent.component.html

1
2
3
4
5
<p>
  parent works!
</p>
Message: {{appParentMessage}}
<app-child (messageEvent)="receiveMessage($event)"></app-child>

child.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  constructor() { }

  message: string = "I am calling from Child Component!"

  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    this.messageEvent.emit(this.message)
  }


child.component.html

1
2
3
4
<p>
  child works!
</p>
<button (click)="sendMessage()">Send Message</button>

pass data from child to parent using output and eventemiitter

Summary

In our post, we have learned about how to share data between parent and child components using @Input(), @Output and EventEmitter. Data sharing is very important concept, and everybody needs to share data between application’s components.

Further reading

Share on

Adesh
WRITTEN BY
Adesh
Technical Architect