Data Sharing – Angular

In Angular, data sharing between components is a common task, and Angular provides several ways to share data between components. You might share data between a parent and child component, between sibling components, or between unrelated components.

Here are some ways to share data between components in Angular 17, with examples:

1. @Input and @Output (Parent-Child Communication)

  • Use @Input() to pass data from a parent to a child component.
  • Use @Output() to emit events from a child to a parent component.

Example: Parent to Child using @Input

  1. Child Component (child.component.ts)
   import { Component, Input } from '@angular/core';

   @Component({
     selector: 'app-child',
     template: `<h3>{{childMessage}}</h3>`
   })
   export class ChildComponent {
     @Input() childMessage: string = '';
   }
  1. Parent Component (parent.component.ts)
   import { Component } from '@angular/core';

   @Component({
     selector: 'app-parent',
     template: `<app-child [childMessage]="message"></app-child>`
   })
   export class ParentComponent {
     message: string = 'Hello from Parent';
   }

In this example, the parent passes the message to the child using the @Input() decorator.

Example: Child to Parent using @Output

  1. Child Component (child.component.ts)
   import { Component, Output, EventEmitter } from '@angular/core';

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

     sendMessage() {
       this.messageEvent.emit('Hello Parent');
     }
   }
  1. Parent Component (parent.component.ts)
   import { Component } from '@angular/core';

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

     receiveMessage(message: string) {
       this.receivedMessage = message;
     }
   }

In this example, the child sends data to the parent using the @Output() decorator.


2. Service with Observable (Sibling or Unrelated Components)

For sharing data between sibling or unrelated components, Angular services and RxJS Observables can be used. This method is useful because the service can act as a common data source for multiple components.

Example: Sharing Data via Service

  1. Data Service (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) {
       this.messageSource.next(message);
     }
   }
  1. First Component (first.component.ts)
   import { Component } from '@angular/core';
   import { DataService } from './data.service';

   @Component({
     selector: 'app-first',
     template: `
       <button (click)="newMessage()">New Message</button>
     `
   })
   export class FirstComponent {
     constructor(private dataService: DataService) {}

     newMessage() {
       this.dataService.changeMessage('Hello from First Component');
     }
   }
  1. Second Component (second.component.ts)
   import { Component, OnInit } from '@angular/core';
   import { DataService } from './data.service';

   @Component({
     selector: 'app-second',
     template: `
       <h3>{{message}}</h3>
     `
   })
   export class SecondComponent implements OnInit {
     message: string = '';

     constructor(private dataService: DataService) {}

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

In this example, the DataService uses BehaviorSubject to maintain a stream of data that can be subscribed to by components. The first component changes the message, and the second component subscribes to the message and gets updates in real-time.


3. Using a Shared Service without Observables

You can also share data using a shared service without RxJS. This method is simpler but less dynamic than using observables.

Example: Sharing Data via a Service

  1. Data Service (data.service.ts)
   import { Injectable } from '@angular/core';

   @Injectable({
     providedIn: 'root',
   })
   export class DataService {
     sharedData: string = 'Initial Data';
   }
  1. Component 1 (component1.component.ts)
   import { Component } from '@angular/core';
   import { DataService } from './data.service';

   @Component({
     selector: 'app-component1',
     template: `
       <button (click)="changeData()">Change Data</button>
     `
   })
   export class Component1 {
     constructor(private dataService: DataService) {}

     changeData() {
       this.dataService.sharedData = 'Updated Data from Component 1';
     }
   }
  1. Component 2 (component2.component.ts)
   import { Component } from '@angular/core';
   import { DataService } from './data.service';

   @Component({
     selector: 'app-component2',
     template: `
       <h3>{{ dataService.sharedData }}</h3>
     `
   })
   export class Component2 {
     constructor(public dataService: DataService) {}
   }

In this example, both components access the same DataService and share a common piece of data via a simple public property.


4. Shared Modules with Singleton Services

If components reside in different modules, you can provide the service at the root level (providedIn: 'root') to make it a singleton and share data across modules.


Conclusion

  • Use @Input and @Output for parent-child communication.
  • Use services with observables for sibling or unrelated components.
  • For simpler scenarios, a shared service without observables can also be used.

Each method has its use case, and understanding when to use each is key to writing clean, scalable Angular applications.

Tags: No tags

Add a Comment

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