Transferring information among various components is a crucial requirement in any application, and Angular is no exception. While this practice is widespread, Angular offers several built-in methods to facilitate it. However, there might be situations where these default approaches fall short, necessitating the implementation of more innovative solutions.

In this session, we will explore a few commonly used methods to communicate between components.

The tools which I have leveraged for the tutorial are given below.

  1. Visual Studio Code
  2. Node 18.14.0
  3. Angular 15

The source code can be downloaded from GitHub

Input and Output Properties (Parent-Child Communication)

Let us look at the sample code below, which will give you an overview of parent-to-child and child-to-parent communications.

Parent Component

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

@Component({
  selector: 'app-parent',
  template: `
    <h1>Parent Component</h1>
    <input [(ngModel)]="parentMessage"/>
    <p>{{ childMessage }}</p>
    <app-child [message]="parentMessage" (notify)="onNotify($event)"></app-child>`
  
})
export class IOParentComponent {
  parentMessage = 'Message from parent';
  childMessage ="";
  onNotify(message: string) {
    this.childMessage =message;
  }
}

Child Component

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

@Component({
  selector: 'app-child',
  template: `
    <h2>Child Component</h2>
    <p>{{ message }}</p>
    <input [(ngModel)]="childMessage"/>
    <button (click)="notifyParent()">Notify Parent</button>
  `
})
export class IOChildComponent {
  @Input() message: string ='';
  @Output() notify = new EventEmitter<string>();
  childMessage: string ='Message from child';
  notifyParent() {
   
    this.notify.emit(this.childMessage);
  }
}

Services (Cross-Component Communication) using RxJS Observables and Subjects

Let us take a look at the example

Shared Service

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable()
export class DataService {
  private dataSubject = new Subject<string>();

  setData(data: string) {
    this.dataSubject.next(data);
  }

  getData() {
    return this.dataSubject.asObservable();
  }
}

Component 1

import { Component } from '@angular/core';
import { DataService } from './dataservice.service';

@Component({
  selector: 'app-scomponent1',
  template: `    <h1>Component 1</h1>
    <input type="text" [(ngModel)]="message">
    <button (click)="sendMessage()">Send Message</button>
    <app-component2>/</app-component2>`
  
})
export class SComponentOne {
  message: string="";

  constructor(private dataService: DataService) { }

  sendMessage() {
    this.dataService.setData(this.message);
  }
}

Component 2

import { Component } from '@angular/core';
import { DataService } from './dataservice.service';

@Component({
  selector: 'app-component2',
  template: `
    <h1>Component 2</h1>
    <p>{{ receivedMessage }}</p>
  `
})
export class SComponentTwo {
  receivedMessage: string ='';

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.dataService.getData().subscribe(message => {
      this.receivedMessage = message;
    });
  }
}

The below reference link explains the Mediator and Service Bus approaches for component communication in Angular.

Component communication in Angular for Senior devs by 'iamprovidence'

These are some of the commonly used methods for component communication in Angular. The choice of method depends on the specific requirements of your application and the relationship between the components involved.