Angular Data Sharing Techniques

Sumanth M J
5 min readMar 29, 2023

--

This article covers several methods for sharing data between components in an Angular application. It introduces the @Input and @Output decorators, @ViewChild, and uses a common service file.

1. Parent to Child: via @Input

@Input is an Angular feature that enables a parent component to send data to a child component. For instance, if we have a parent component called “parent” and a child component called “child”, we can use @Input to pass data from the parent to the child by declaring a property in the child component with the @Input decorator.

For example, in the child component’s TypeScript file, we can declare a property like this:

@Input() childData: string;

In the parent component’s HTML file, we can bind this property to a value like this:

<child-component [childData]="parentData"></child-component>

This will pass the value of “parentData” to the child component’s “childData” property, enabling it to use that value in its logic and display.

2. Child to Parent: via @Output

@Output is a powerful Angular feature that allows a child component to emit data to its parent component. It works by defining a custom event in the child component with the help of EventEmitter.

For instance, in the child component’s TypeScript file, we can define an event like this:

@Output() childEvent = new EventEmitter<string>();

In the child component’s logic, we can emit the event like this:

this.childEvent.emit('Hello from child component!');

In the parent component’s HTML file, we can listen for the event and respond accordingly like this:

<child-component (childEvent)="onChildEvent($event)"></child-component>

This will call the “onChildEvent” method in the parent component whenever the child component emits the event, and we can pass the emitted data as an argument.

3. Child to Parent: via @ViewChild

@ViewChild is an Angular decorator that allows a parent component to access a child component or element directly. It provides the parent component with more control over the child component’s data and behavior. For example, you can use @ViewChild to access a child component’s methods, properties, or even its DOM elements.

Here’s an example:

Accessing a child component’s method:

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

@Component({
selector: 'parent-component',
template: `
<child-component></child-component>
`
})
export class ParentComponent {
@ViewChild(ChildComponent) childComponent: ChildComponent;

ngAfterViewInit() {
this.childComponent.someMethod();
}
}

Accessing a child component’s property:

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

@Component({
selector: 'parent-component',
template: `
<child-component></child-component>
`
})
export class ParentComponent {
@ViewChild(ChildComponent) childComponent: ChildComponent;

ngAfterViewInit() {
console.log(this.childComponent.someProperty);
}
}

Accessing a child component’s DOM element:

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

@Component({
selector: 'parent-component',
template: `
<child-component></child-component>
`
})
export class ParentComponent {
@ViewChild(ChildComponent) childComponent: ChildComponent;
@ViewChild('childElement') childElement: ElementRef;

ngAfterViewInit() {
console.log(this.childElement.nativeElement);
}
}

In this example, we are using ViewChild to access the child component and then access a specific DOM element within the child component using ElementRef. The child component's template might look like this:

<child-component>
<div #childElement>This is a child element</div>
</child-component>

4. Unrelated Components: via a Service

In Angular, when you need to share data between components that are not directly related to each other, you can use a shared service. A shared service is a class that can be injected into multiple components and provides a common place to store data that needs to be shared between them. By using a shared service, you can avoid passing data between components through complex event chains and instead provide a centralized and organized approach to data sharing. This makes your application more maintainable and scalable over time and allows for a more efficient development process.

Here’s an example:

First, create a new service file using the ng generate service command in the terminal:

ng generate service shared

Open the shared.service.ts file and declare a variable that will store the shared data:

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

@Injectable({
providedIn: 'root'
})
export class SharedService {
sharedData: string;
}

In the component that needs to set the shared data, import the SharedService and inject it into the constructor:

import { Component } from '@angular/core';
import { SharedService } from '../shared.service';

@Component({
selector: 'app-component-a',
template: `
<button (click)="setSharedData()">Set shared data</button>
`
})
export class ComponentA {
constructor(private sharedService: SharedService) {}

setSharedData() {
this.sharedService.sharedData = 'This is shared data';
}
}

In the component that needs to access the shared data, import the SharedService and inject it into the constructor:

import { Component } from '@angular/core';
import { SharedService } from '../shared.service';

@Component({
selector: 'app-component-b',
template: `
<div>{{ sharedData }}</div>
`
})
export class ComponentB {
sharedData: string;

constructor(private sharedService: SharedService) {
this.sharedData = this.sharedService.sharedData;
}
}

Now, when the user clicks the “Set shared data” button in ComponentA, the sharedData variable in the SharedService will be set to "This is shared data". Then, in ComponentB, the sharedData variable will be set to the same value as the sharedData variable in the SharedService. This way, both components have access to the same shared data.

Summary

This blog explains the various methods for sharing data between components in Angular. Techniques such as @Input and @Output, @ViewChild, and a common service file are discussed. By using the appropriate method for your use case, you can create more flexible, maintainable, and scalable applications.

--

--

No responses yet