Angular Pass Data Between Components Tutorial | @Input, @Output & ViewChild - Tutorial Rays
Angular 20

Angular Pass Data Between Components Tutorial | @Input, @Output & ViewChild

🚀 Angular Pass Data Tutorial: Parent to Child, Child to Parent & ViewChild

In Angular, components are used to divide an application into small reusable parts. Many times, we need to pass data from one component to another component. Angular provides different ways to share data between components.

In this tutorial, we will learn the 3 most important ways to pass data in Angular:

  • Parent Component to Child Component using @Input()
  • Child Component to Parent Component using @Output() and EventEmitter
  • Access Child Component from Parent using @ViewChild()

1. 📌 Parent to Child Data Passing using @Input()

When we want to send data from a parent component to a child component, we use @Input().

✅ Example Structure

src/app/
│
├── parent/
│   ├── parent.component.ts
│   └── parent.component.html
│
└── child/
    ├── child.component.ts
    └── child.component.html

📄 parent.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html'
})
export class ParentComponent {

  parentMessage: string = 'Hello Child, this message is coming from Parent Component';

}

📄 parent.component.html

<h2>Parent Component</h2>

<app-child [messageFromParent]="parentMessage"></app-child>

📄 child.component.ts

import { Component, Input } from '@angular/core';

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

  @Input() messageFromParent: string = '';

}

📄 child.component.html

<h3>Child Component</h3>

<p>{{ messageFromParent }}</p>

🧠 Explanation

  • @Input() is used inside the child component.
  • The parent sends data using property binding.
  • [messageFromParent]=”parentMessage” means parentMessage value is passed to the child.

2. 📌 Child to Parent Data Passing using @Output()

When we want to send data from a child component to a parent component, we use @Output() with EventEmitter.

📄 child.component.ts

import { Component, Output, EventEmitter } from '@angular/core';

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

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

  sendMessage() {
    this.sendDataToParent.emit('Hello Parent, this message is coming from Child Component');
  }

}

📄 child.component.html

<h3>Child Component</h3>

<button (click)="sendMessage()">Send Message to Parent</button>

📄 parent.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html'
})
export class ParentComponent {

  childMessage: string = '';

  receiveMessage(data: string) {
    this.childMessage = data;
  }

}

📄 parent.component.html

<h2>Parent Component</h2>

<app-child (sendDataToParent)="receiveMessage($event)"></app-child>

<p>Message from Child: {{ childMessage }}</p>

🧠 Explanation

  • @Output() creates a custom event.
  • EventEmitter emits data from child to parent.
  • The parent listens using event binding.
  • $event receives the data sent from the child component.

3. 📌 Parent Access Child using @ViewChild()

Sometimes, the parent component needs to directly access a child component method or variable. For this, Angular provides @ViewChild().

📄 child.component.ts

import { Component } from '@angular/core';

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

  childName: string = 'Angular Child Component';

  showChildMessage() {
    return 'This method is called from Child Component';
  }

}

📄 child.component.html

<h3>Child Component</h3>

<p>Child component is working!</p>

📄 parent.component.ts

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

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html'
})
export class ParentComponent implements AfterViewInit {

  @ViewChild(ChildComponent) childComponent!: ChildComponent;

  childData: string = '';
  childMethodMessage: string = '';

  ngAfterViewInit() {
    this.childData = this.childComponent.childName;
    this.childMethodMessage = this.childComponent.showChildMessage();
  }

}

📄 parent.component.html

<h2>Parent Component</h2>

<app-child></app-child>

<p>Child Variable Value: {{ childData }}</p>

<p>Child Method Message: {{ childMethodMessage }}</p>

🧠 Explanation

  • @ViewChild() allows parent to access child component.
  • It can access child variables and methods.
  • ngAfterViewInit() is used because the child view is available after the view is initialized.

⚡ Complete Comparison Table

Method Direction Decorator Used Best Use Case
Parent to Child Parent → Child @Input() Send data like title, user info, product details
Child to Parent Child → Parent @Output() Send button click, form data, selected value
ViewChild Parent accesses Child @ViewChild() Call child method or access child property

🎯 Real-Life Example

Suppose we are building a student management application.

  • Parent component has student data.
  • Child component displays student details.
  • Child component sends selected student back to parent.
  • Parent can also call child methods using ViewChild.

📄 parent.component.ts

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { StudentChildComponent } from '../student-child/student-child.component';

@Component({
  selector: 'app-student-parent',
  templateUrl: './student-parent.component.html'
})
export class StudentParentComponent implements AfterViewInit {

  studentName: string = 'Rahul Kumar';
  selectedStudent: string = '';

  @ViewChild(StudentChildComponent) studentChild!: StudentChildComponent;

  ngAfterViewInit() {
    console.log(this.studentChild.childInfo());
  }

  getStudentFromChild(student: string) {
    this.selectedStudent = student;
  }

}

📄 parent.component.html

<h2>Student Parent Component</h2>

<app-student-child 
  [student]="studentName"
  (studentSelected)="getStudentFromChild($event)">
</app-student-child>

<p>Selected Student: {{ selectedStudent }}</p>

📄 student-child.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-student-child',
  templateUrl: './student-child.component.html'
})
export class StudentChildComponent {

  @Input() student: string = '';

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

  selectStudent() {
    this.studentSelected.emit(this.student);
  }

  childInfo() {
    return 'Student Child Component Loaded Successfully';
  }

}

📄 student-child.component.html

<h3>Student Child Component</h3>

<p>Student Name: {{ student }}</p>

<button (click)="selectStudent()">Select Student</button>

🧪 Practical Assignment

✅ Assignment Task

Create an Angular application with two components:

  • ParentComponent
  • ChildComponent

You have to implement all 3 ways of passing data:

  1. Send course name from parent to child using @Input()
  2. Send selected course back from child to parent using @Output()
  3. Call child component method from parent using @ViewChild()

📋 Expected Output

Parent Component
Course sent to child: Angular Full Course

Child Component
Course Name: Angular Full Course

Button: Send Course to Parent

Parent receives:
Selected Course: Angular Full Course

ViewChild Message:
Child method called successfully

💡 Important Notes

  • Use @Input() when parent sends data to child.
  • Use @Output() when child sends data to parent.
  • Use @ViewChild() when parent needs direct access to child component.
  • Use ngAfterViewInit() with ViewChild because child view is available after initialization.

✅ Final Summary

Question Answer
How to pass data from parent to child? Using @Input()
How to pass data from child to parent? Using @Output() and EventEmitter
How to access child method from parent? Using @ViewChild()
Which lifecycle hook is used with ViewChild? ngAfterViewInit()

Leave a Reply

Your email address will not be published. Required fields are marked *