Wednesday, October 26, 2022

How Components Communicate With Each Other In Angular


How Components Communicate With Each Other In Angular

 Components are the building blocks of Angular. So we need to understand how components communicate with each other.

There are three ways:

  1. parent to child - sharing data via input 
  2. child to parent - sharing data via viewChild with AfterViewInit
  3. child to parent - sharing data via output and EventEmitter
How Components Communicate With Each Other In Angular

Parent to child - sharing data via input
To share data from parent component to child component we use@input decorator.

Let’s configure the parent component and child component,
import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: ` <app-child [childMessage]="message"></app-child> `,
  styleUrls: ['./parent.component.css']
})

export class ParentComponent {
  message = “I am a parent"
  constructor() { }
}

If you see the above code, <app-child> is used as a directive in the parent component. we are using property binding to bind the properties between child and parent, Binding child’s childMessage property with message property from the parent component. 

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

@Component({
  selector: 'app-child',
  template: ` {{ message }}  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  @Input() childMessage: string;
  constructor() { }
}

To use@input decorative, we have to first import it from @angular/core . Next will decorate childMessage with @input decorative with type string. Lastly, display the message from the parent into the child template using string interpolation.


Child to parent - sharing data via ViewChild and AfterViewInit
It allows the child component to be injected into parent competent so that the parent component gets access to its child’s attributes and functions. We must note that parents will get access only after the view is initialized.

Let’s configure the parent component and child component

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

@Component({
  selector: 'app-parent',
  template: `
    Message: {{ message }}
    <app-child></app-child>
  `,
  styleUrls: ['./parent.component.css']
})

export class ParentComponent implements AfterViewInit {

  @ViewChild(ChildComponent) child;
  constructor() { }

  Message:string;

  ngAfterViewInit() {
    this.message = this.child.message
  }
}
JavaScript
import { Component} from '@angular/core';

@Component({
  selector: 'app-child',
  template: `  `,
  styleUrls: ['./child.component.css']
})

export class ChildComponent {
  message = 'Hello Angular!';
  constructor() { }
}

We have to import ViewChild,AfterViewInit from angular/core, and the child component and use AfterViewInit life cycle hook so that we get access to the attributes in the child component. In the child component, we are passing the value for the message.

Child to parent - sharing data via output and EventEmitter
You use this approach when you want to share the data on button clicks or other events. The child component uses @output to send the data to the parent by creating an event with the help of an EventEmitter which is imported from @angular/core.

Let’s configure the parent component and child component.
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
      <button (click)="message()">Send Message</button>
 `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  message: string = "Hey I am child !"
  @Output() messageEvent = new EventEmitter<string>();
 constructor() { }
  sendMessage() {
    this.messageEvent.emit(this.message)
  }
}

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

@Component({
  selector: 'app-parent',
  template: `
    Message: {{message}}
    <app-child (messageEvent)="receiveMessage($event)"></app-child>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {
    constructor() { }
    Message:string;
    receiveMessage($event) {
        this.message = $event
    }
}
JavaScript
First, we have to import output and EventEmitter from the @anguar/core , then we are creating an event messageEvent using EventEmitter . when the button is clicked it calls the function sendMessage and calls the emit with the message. we are using event binding property with the child selector . The parent can now subscribe to this messageEvent that’s outputted by the child component, then run the receive message function whenever this event occurs.