How to Communicate between Angular Components

Angular is purely driven through Component based architecture. Components are like basic building blocks in an Angular application. These components can also be nested such as there may be many child components to a single parent component. A component has a selector, template,style and other properties and it is defined using an @component decorator.

In this blog, we are going to see how we can communicate between the components which have the following relationships.

  • Communication from Parent to Child Component
  • Communication from Child to Parent Component
  • Communication between two different Components

Communication from Parent to Child Component

Let us consider the below image. Here you can see two components app component(Parent Component) and the child Component(Child Component).

If you want to send a value from app component to child component we use @Input() decorator in the child component to receive the respective value from the parent component.

app.component.ts

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

@Component({
  selector: "app-component",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent  {
   count: number = 10; 
   //value which will be sent to child
}

app.component.html

<app-child [count]="count"></app-child>

So from the above code we are passing the value of count from the parent component to child component using property binding: [property].

child.component.ts

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

@Component({
  selector: "app-child",
  templateUrl: "./child/child.component.html",
  styleUrls: ["./child/child.component.css"]
})
export class AppComponent  {
   @Input() count: number;
   //value will be 10
}

So we have received the value of count using the @Input() decorator. You can see it’s very easy to pass an value from parent to child component.

Communication from Child to Parent Component

If you want to communicate from child component to parent component we use @Output() decorator and EventEmitter. Let us take same project structure, app component and the child component.

child.component.ts

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

@Component({
  selector: "app-child",
  templateUrl: "./child/child.component.html",
  styleUrls: ["./child/child.component.css"]
})
export class AppComponent implements OnInit  {
   @Input() count: number;
   @Output() emitEvent: EventEmitter<string> 
               = new EventEmitter();
   
   ngOnInit(){
       this.emitEvent.emit("nullablereference");
       // passing a string value from child to parent
   }
}

So from the above code snippet you can see we are emitting a string called “nullablereference” with the help of emitEvent EventEmitter from child to parent using @Output() decorator.

app.component.html

<app-child [count]="count" 
           (emitEvent)="onValueChange($event)">
</app-child>

app.component.ts

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

@Component({
  selector: "app-component",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent  {
   count: number = 10;
   
   onValueChange(event){
     console.log(event);
     //it will print as nullablereference 
   }
}

Basically we have received the value from html and you can pass that to your respective ts file and you can make use of that value for further operations.

Communication between two different Components

Lets take a scenario where the components does not have a relation like parent or child and they are independent of each other. If you want to pass any value between these two components, you should make use of service and BehaviourSubject or Subject in RxJS.

helper.service.ts

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

@Injectable({
  providedIn: 'root'
})
export class HelperService {

  onValueChanged: BehaviorSubject<number>
              = new BehaviorSubject(undefined);

  constructor() { }
}

Here we have an BehaviourSubject called onValueChanged which can used to emit a value and also you can subscribe to get the current value.

hello.component.ts

import { Component, OnInit } from '@angular/core';
import { HelperService } from '../../services/helper.service';

@Component({
  selector: 'app-hello-world',
  templateUrl: './hello-world.component.html',
  styleUrls: ['./hello-world.component.scss']
})
export class HelloWorldComponent implements OnInit {

  constructor(public _helperService: HelperService) { }

  ngOnInit() {
    this._helperService.onValueChanged.next(1);
    //setting the value of onValueChanged to 1
  }
}

hello component and thank you component are independent of each other. In this component we have injected _helperService and we have made the value of onValueChanged to 1.

thank-you.component.ts

import { Component, OnInit } from '@angular/core';
import { HelperService } from '../../services/helper.service';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-thank-you',
  templateUrl: './thank-you.component.html',
  styleUrls: ['./thank-you.component.scss']
})
export class ThankYouComponent implements OnInit {
  public value: number;
  private ngUnSubscribe = new Subject();

  constructor(private _helperService: HelperService) { }

  ngOnInit() {

    //To take the current value of onValueChanged
    this.value = this._helperService.onValueChanged.value;// value will be 1

    //To take the value of onValueChanged whenever it gets changed
    this._helperService.onValueChanged
            .pipe(takeUntil(this.ngUnSubscribe))
            .subscribe(response => {
              this.value = response; //value will be 1
            });
  }
}

After injecting the _helperService, here there are two cases,

  • If you want to get the value only once, you can directly use onValueChanged.value.
  • If you want to get the respective value of onValueChanged whenever there is a change in that respective value in any other component, you should subscribe to it and you shall get the current value of it.

GitHub Link => https://github.com/SuhasParameshwara/AngularComponentCommunication

Conclusion

And also we have ViewChild and ContentChild to get the value from the Child Component. But most of the times, we wont use that and all the communication between the components can be done by,

  • @Input()
  • @Output() and EventEmitter
  • Service and (Subject or Behaviour Subject)

By using these decorators and attributes you should be able to communicate between the components which have parent child relationship or vice versa and also if the components are independent to each other.

So in our next blog we shall see about Angular Forms.

Happy Coding!

Cheers 😉

One thought on “How to Communicate between Angular Components

Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: