communication between components in angular with code examples

Angular is a powerful front-end framework that offers a vast array of tools for building web applications. One of the key features that make Angular so popular is its ability to communicate between components through its hierarchy of components. This allows developers to create complex web applications with ease.

Communication between components is a crucial aspect of every web application, and Angular provides developers with several methods to achieve this. In this article, we will explore different ways to communicate between components in Angular and examine code examples that demonstrate how these methods work.

  1. Input and Output Decorators

Input and Output decorators are the most common way to communicate between components in Angular. Input decorators allow developers to pass data from a parent component to a child component, while Output decorators allow developers to emit events from a child component to a parent component.

Input Decorator

The Input decorator is used to decorate a class property. It defines how data from the parent component is passed to the child component. Here’s an example:

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

@Component({
  selector: 'app-child',
  template: `
    <div>
      <h1>Welcome {{ name }}</h1>
    </div>
  `,
})
export class ChildComponent {
  @Input() name: string;
}

In the code above, we have a child component that receives data from a parent component. The @Input() decorator is used to pass the data from the parent component as an input property to the child component.

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: `
    <div>
      <app-child [name]="name"></app-child>
    </div>
  `,
})
export class ParentComponent {
  name = 'Angular';
}

In the code above, the name property is defined in the parent component and passed to the child component using the [name] syntax. This allows the child component to receive the value of the name property and display it in the template.

Output Decorator

The Output decorator allows developers to emit events from a child component to a parent component. Here’s an example:

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

@Component({
  selector: 'app-child',
  template: `
    <div>
      <button (click)="sendMessage()">Send Message</button>
    </div>
  `,
})
export class ChildComponent {
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    this.messageEvent.emit('Hello from Child Component!');
  }
}

In the code above, the sendMessage method is triggered when the button is clicked, and it uses the messageEvent to emit an event that sends a message to the parent component.

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: `
    <div>
      <app-child (messageEvent)="receiveMessage($event)"></app-child>
      <p>{{ message }}</p>
    </div>
  `,
})
export class ParentComponent {
  message: string;

  receiveMessage($event) {
    this.message = $event;
  }
}

In the code above, the parent component receives the message sent from the child component using the $event parameter in the receiveMessage method. The parent component then updates the message property, which is displayed in the template.

  1. Service

Another way to communicate between components in Angular is through services. A service is a class that is responsible for providing a specific functionality to the rest of the application. Services can be used to share data, functions, or any other functionality between components.

Here’s an example:

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

@Injectable({
  providedIn: 'root',
})
export class DataService {
  message: string;
}

In the code above, we have a DataService that is responsible for sharing data between components. The message property is defined in the DataService class, and it will be shared between all components that use this service.

Child Component:

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

@Component({
  selector: 'app-child',
  template: `
    <div>
      <h1>Welcome {{ name }}</h1>
      <p>{{ message }}</p>
    </div>
  `,
})
export class ChildComponent {
  name = 'Angular';

  constructor(private dataService: DataService) {}

  get message() {
    return this.dataService.message;
  }
}

In the code above, the child component retrieves the message property from the DataService using dependency injection. The get method is used to retrieve the message property from the DataService.

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: `
    <div>
      <app-child></app-child>
      <button (click)="sendMessage()">Send Message</button>
    </div>
  `,
})
export class ParentComponent {
  constructor(private dataService: DataService) {}

  sendMessage() {
    this.dataService.message = 'Hello from Parent Component!';
  }
}

In the code above, the parent component sends a message to the DataService by setting the message property to a new value. This new value is then retrieved by the child component, which displays it in the template.

Conclusion

In this article, we explored three different ways to communicate between components in Angular. The first method involved using Input and Output Decorators to pass data between parent and child components. The second method involved using a shared service to exchange data between components. Finally, we demonstrated how to emit events from a child component to a parent component through the use of Output Decorators.

Each method is powerful in its own right and can be used in different scenarios depending on the specific requirements of a web application. Mastering these communication techniques is essential to building complex, robust, and scalable web applications in Angular.

I am happy to add more information about the previous topics.

  1. Input and Output Decorators

Input and Output decorators are a great way to communicate between parent and child components in Angular. These decorators are used to create bindings between the parent and child components.

Input Decorator

The Input decorator is used to pass data from a parent component to a child component. Here, the parent component passes data to the child component through an input property.

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

@Component({
  selector: 'app-child',
  template: `
    <div>
      <h1>Welcome {{ name }}</h1>
    </div>
  `,
})
export class ChildComponent {
  @Input() name: string;
}

In the code above, we have a child component that receives data from a parent component. The @Input() decorator is used to pass the data from the parent component as an input property to the child component.

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: `
    <div>
      <app-child [name]="name"></app-child>
    </div>
  `,
})
export class ParentComponent {
  name = 'Angular';
}

In the code above, the name property is defined in the parent component and passed to the child component using the [name] syntax. This allows the child component to receive the value of the name property and display it in the template.

Output Decorator

The Output decorator is used to emit events from a child component to a parent component. Here, the child component emits an event using the Output decorator and the parent component listens for the event.

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

@Component({
  selector: 'app-child',
  template: `
    <div>
      <button (click)="sendMessage()">Send Message</button>
    </div>
  `,
})
export class ChildComponent {
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    this.messageEvent.emit('Hello from Child Component!');
  }
}

In the code above, the sendMessage method is triggered when the button is clicked. It uses the messageEvent EventEmitter to emit an event that sends a message to the parent component.

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: `
    <div>
      <app-child (messageEvent)="receiveMessage($event)"></app-child>
      <p>{{ message }}</p>
    </div>
  `,
})
export class ParentComponent {
  message: string;

  receiveMessage($event) {
    this.message = $event;
  }
}

In the code above, the parent component receives the message sent from the child component using the $event parameter in the receiveMessage method. The parent component then updates the message property, which is displayed in the template.

  1. Service

Services are another way to communicate between components in Angular. A service is a class that is responsible for providing a specific functionality to the rest of the application. It is a singleton that can be used across multiple components.

Here's an example of a DataService:

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

@Injectable({
  providedIn: 'root'
})
export class DataService {
  message: string;

  constructor() { }
}

The @Injectable decorator is required to register the service with the Angular DI (Dependency Injection) system. The providedIn property of the decorator registers the service at the root level. This means that the service is available throughout the entire application.

Child Component:

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

@Component({
  selector: 'app-child',
  template: `
    <div>
      <h1>Welcome {{ name }}</h1>
      <p>{{ message }}</p>
    </div>
  `,
})
export class ChildComponent {
  name = 'Angular';
  message: string;

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.message = this.dataService.message;
  }
}

In the code above, the message property is retrieved from the DataService using dependency injection. The ngOnInit method is used to retrieve the message property from the DataService and set it as a property of the ChildComponent.

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: `
    <div>
      <app-child></app-child>
      <button (click)="sendMessage()">Send Message</button>
    </div>
  `,
})
export class ParentComponent {
  constructor(private dataService: DataService) {}

  sendMessage() {
    this.dataService.message = 'Hello from Parent Component!';
  }
}

In the code above, the parent component sends a message to the DataService by setting the message property to a new value. This new value is then retrieved by the child component, which displays it in the template.

In conclusion, there are several ways to communicate between components in Angular. Input and Output decorators, services, and observables are all useful methods to use depending on the use case. By mastering these techniques, developers can create robust web applications that are easy to maintain and scale.

Popular questions

Sure, here are 5 questions and their answers related to communication between components in Angular.

  1. What is the purpose of the Input and Output decorators in Angular?
    Answer: The Input and Output decorators are used to create bindings between the parent and child components. Input decorators allow the parent to pass data to the child and Output decorators allow the child to emit events that the parent can listen for.

  2. What is a service in Angular and how is it used for communication between components?
    Answer: An Angular service is a class that provides a specific functionality to the rest of the application and can be used for communication between components. Services are singletons that can be injected into multiple components and allow developers to share data, functions, or any other functionality across components.

  3. What is the purpose of the EventEmitter in Angular?
    Answer: An EventEmitter in Angular is a class that allows components to emit events. It is used to communicate between components by allowing a child component to send a message to the parent component. EventEmitter is used in conjunction with the Output decorator and allows components to emit custom events that can be listened to by parent components.

  4. Can multiple child components use the same service to communicate with each other?
    Answer: Yes, multiple child components can use the same service to communicate with each other. The service acts as a central point of communication and provides a shared space for components to communicate with each other. Components can obtain data from the service and update it, which is then shared with other child components that use the same service.

  5. Which method of communication between components in Angular is best for large-scale applications?
    Answer: The best method for communication between components in large-scale applications depends on the specific use case. However, using a shared service is a common approach to communication between components in Angular. Services provide a centralized location for communication, making it easier to manage data and functions across components. Additionally, services can be easily injected into any component, allowing for increased scalability and flexibility in larger applications.

Tag

"Angular Intercommunication."

Code examples:

  1. Using @Input and @Output decorators to pass data between child and parent components:
// child.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss']
})
export class ChildComponent {
  @Input() message: string;
  @Output() handleClick = new EventEmitter();

  onClick(): void {
    this.handleClick.emit();
  }
}

// parent.component.html
<app-child [message]="parentMessage" (handleClick)="handleClick()"></app-child>
  1. Using a shared service to communicate between components:
// data.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class DataService {
  private messageSource = new BehaviorSubject<string>('default message');
  currentMessage = this.messageSource.asObservable();

  changeMessage(message: string): void {
    this.messageSource.next(message);
  }
}

// child.component.ts
import { Component } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss']
})
export class ChildComponent {
  message: string;

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.dataService.currentMessage.subscribe(message => this.message = message);
  }

  onClick(): void {
    this.dataService.changeMessage('new message');
  }
}

// parent.component.ts
import { Component } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss']
})
export class ParentComponent {
  message: string;

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.dataService.currentMessage.subscribe(message => this.message = message);
  }

  handleClick(): void {
    this.dataService.changeMessage('clicked from parent');
  }
}
As a senior DevOps Engineer, I possess extensive experience in cloud-native technologies. With my knowledge of the latest DevOps tools and technologies, I can assist your organization in growing and thriving. I am passionate about learning about modern technologies on a daily basis. My area of expertise includes, but is not limited to, Linux, Solaris, and Windows Servers, as well as Docker, K8s (AKS), Jenkins, Azure DevOps, AWS, Azure, Git, GitHub, Terraform, Ansible, Prometheus, Grafana, and Bash.

Leave a Reply

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

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top