Component Interaction in Angular
Tags: javascript, webdev, tutorial, angular
Published: 2022-04-15 14:04:14

Hello guys, I am writing my first blog on Angular. As we know, Angular is a module-component based frontend-end framework.

By this tutorial, you can learn, how we can share data between component in Angular in different way. I am providing those way then you can understand easily.

1. Communication through Parent Component to Child Component (Input Decorator)
2. Communication through Child Component to Parent Component (ViewChild Decorator)
3. Communication through Child Component to Parent Component (Output/EventEmitter Decorator)
4. Communication through Sibling Components (As a service)

**

## Communication through Parent Component to Child Component (Input Decorator)
**
Most common way to introduce data share via Input decorator that allow data to passed via template with data binding. Here, data list sharing via parent component to child component. I am showing a data list via this way.

**parent.component.ts**

```
@Component({
  selector: 'app-parent',
  template: `<app-child [data]="dataList"></app-child>`,
  styleUrls: ['./parent.component.scss']
})
export class ParentComponent implements OnInit {
  public dataList: ParentDataList[] = PARENT_DATA_LIST;
  constructor() { }
  ngOnInit(): void {
  }
}
```
**child.component.ts**

```
@Component({
  selector: 'app-child',
  template: `<div class="table-responsive">
  <table class="table">
    <tr>
      <th>Id</th>
      <th>User ID</th>
      <th>Title</th>
      <th>Body</th>
    </tr>
    <tr *ngFor="let item of data">
      <td>{{item.id}}</td>
      <td>{{item.userId}}</td>
      <td>{{item.title}}</td>
      <td>{{item.body}}</td>
    </tr>
  </table>
</div>`,
  styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit {
  @Input() data!: ParentDataList[];
  constructor() { }
  ngOnInit(): void {
  }
}
```

**

## Communication through Child Component to Parent Component (ViewChild Decorator)
**
ViewChild decorator , we can passed data via child component to parent component. When we inject ViewChild into parent component, then it give access to parent with it’s variables and functions, then we can use as per our requirement. I am trying to add list via this way.

**parent.component.ts**

```
@Component({
  selector: 'app-parent',
  template: `<button class="primary-btn" (click)="addList()">Add List</button>
<app-child></app-child>`,
  styleUrls: ['./parent.component.scss']
})
export class ParentComponent implements OnInit, AfterViewInit {
  @ViewChild(ChildComponent) child!: ChildComponent;
  constructor() { }
  ngOnInit(): void {
  }
  addList(){
     let obj = {
        id: 1,
        userId: 123,
        title: 'ankit',
        body:'every thing mcm complrter'
      }
     this.child.arrList = [...this.child.arrList, obj];
  }
  ngAfterViewInit(){
    this.child.showList(true);
  }
}
```
**child.component.ts**

```
@Component({
  selector: 'app-child',
  template: `<table *ngIf="collapseList" class="table">
  <tr *ngFor="let item of arrList;let i=index;">
    <td>{{item.id}}{{i}}</td>
    <td>{{item.userId}}{{i}}</td>
    <td>{{item.title}}{{i}}</td>
    <td>{{item.body}}{{i}}</td>
  </tr>
</table>`,
  styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit {
  public collapseList!: boolean
  public arrList:DataList[] = [];
  constructor() { }
  ngOnInit(): void {}
  showList(value:any){
    this.collapseList = value;
  }
}
```
**

## Communication through Child Component to Parent Component (Output/EventEmitter Decorator)
**

Output decorator, This is the another way to share data from child component to parent component via event emitter, as in emit data from the child component to parent component. It works like a event binding in angular. We can share data on any type of event occur via this way like on change, on click etc. I create a small addition/multiply/subtraction/divide functionality by this way.

**parent.component.ts**

```
@Component({
  selector: 'app-parent',
  template: `<div class="row">
  <div class="col-md-2">
    <input #text1 (change)="text1Data(text1.value)" type="number" value="0" class="form-control">
  </div>
  <div class="col-1">
    <h2 class="ak-title-lg">{{optSymbal}}</h2>
  </div>
  <div class="col-md-2">
    <input #text2 (change)="text2Data(text2.value)" type="number" value="0" class="form-control">
  </div>
  <div class="col-md-1">
    <p class="ak-title">=</p>
  </div>
  <div class="col-md-3">
    <input type="text" class="form-control" [value]="result" disabled>
  </div>
</div>
<app-child (btnClick)="operationClick($event)"></app-child>`,
  styleUrls: ['./parent.component.scss']
})
export class ParentComponent implements OnInit {
  public inputValue1: number = 0;
  public inputValue2: number = 0;
  public result: number = 0;
  public optSymbal:any;
  constructor() {}
  text2Data(value: number) {
    this.inputValue2 = value;
  }
  text1Data(value: number) {
    this.inputValue1 = value;
  }
  ngOnInit(): void {}
  operationClick($event: any) {
    this.optSymbal = $event;
    switch ($event) {
      case OPERATION.addition:
        this.result = this.inputValue1 + this.inputValue2;
        break;
      case OPERATION.subtract:
        this.result = this.inputValue1 - this.inputValue2;
        break;
      case OPERATION.multiply:
        this.result = this.inputValue1 * this.inputValue2;
        break;
      case OPERATION.division:
        this.result = this.inputValue1 / this.inputValue2;
        break;
      default:
        break;
    }
  }
}
```

**child.component.ts**

```
@Component({
  selector: 'app-child',
  template: `<table class="table">
  <tr class="row">
    <td class="col-md-3 col-6" *ngFor="let item of btnArr;let i=index;">
      <button class="primary-btn" (click)="changeData(item.opt)">{{item.title}}</button>
    </td>
  </tr>
</table>`,
  styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit {
  @Output() btnClick:EventEmitter<any> = new EventEmitter();
  btnArr = BTN_OPERATION_ARR;
  constructor() { }
  ngOnInit(): void {
  }
  changeData(value:string){
    this.btnClick.emit(value);
  }
}
```
**

## Communication through Sibling Components (As a service)
**

In this way, we can use multiple scenario like via RxJS, get/set methods and more ways. I am explaining here via getter/setter methods, with RxJS BehaviorSubject will discuss in next blog. So I am trying to show and hide a data via service method.

**sibling1.component.ts**

```
@Component({
  selector: 'app-sibling1',
  template: `<p>sibling1 works!</p>
<h2 class="ak-title">This is a <span [ngClass]="{'true': show_flag, 'false': !show_flag}">{{show_flag ? 'True':'False'}}</span> condition</h2>
<a class="primary-btn" routerLink="child">Go to child >>></a>`,
  styleUrls: ['./sibling1.component.scss']
})
export class Sibling1Component implements OnInit {
  show_flag:any;
  constructor(private dataService: DataService) { }
  ngOnInit() {
    this.getData()
  }
  getData(){
    this.show_flag = this.dataService.getData();
  }
}
```

**sibling2.component.ts**

```
@Component({
  selector: 'app-sibling2',
  template: `<button class="primary-btn" routerLink="/">Back</button>
<app-contact [data]="contactData"></app-contact>
<p>child works!</p>
<button class="secondary-btn" (click)="changeCondition()">Change Condition</button><br><br>
<a class="primary-btn" routerLink="/service-based"> <<< Go to Parent</a>`,
  styleUrls: ['./sibling2.component.scss']
})
export class Sibling2Component implements OnInit {
  contactData = CONTACT_HEADER;
  constructor(private dataService: DataService) { }
  changeValue:any;
  ngOnInit() {
    this.changeValue = this.dataService.getData();
  }
  changeCondition(){
    this.changeValue = !this.changeValue;
    this.dataService.setData(this.changeValue);
    alert('Done, Now click on Go to Parent');
  }
}
```
**data.service.ts**

```
@Injectable({
  providedIn: 'root'
})
export class DataService {
  public isEnable: boolean = false;
  constructor() { }
  // we are communication data between two component via service -- getter/setter method
  //-----------------------------------------------------------
  // setter method
  setData(data:any){
    this.isEnable = data;
  }
  // getter method
  getData(){
    return this.isEnable;
  }
}
```
If you have any query or doubts, please quick add comment, will try to resolve your query.

**[GitHub Source Code](https://github.com/ankitkumarsharma/angular-component-interaction)**
**[Demo](https://ankitkumarsharma.github.io/angular-component-interaction/#/home)**

[https://www.ankitkumarsharma.com/](https://www.ankitkumarsharma.com/)

Also please follow me on [GitHub](https://github.com/ankitkumarsharma) , [Twitter](https://twitter.com/ankit_k_sharma) , [Medium](https://medium.com/@ankit_k_sharma), and [Dev](https://dev.to/ankit_k_sharma) for more updates on articles with hands on code queries.