- Subject as an Observable and Observer: A Subject in RxJS acts as both an Observable and an Observer. When values are emitted through the Subject using its next() method, all subscribers to the Subject will receive those values.
- Multiple Subscriptions: When multiple subscriptions are made to the same Subject, each subscriber will independently handle emitted values, but all receive the same data simultaneously.
- Angular's Dependency Injection: If the Subject is provided with a service and that service is injected into multiple components, those components share the same instance as the Subject.
Example. Subject with Multiple Subscribers
Here’s an example demonstrating multiple subscriptions to a Subject in Angular.
Service with Subject
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root', // Singleton service
})
export class DataService {
private dataSubject = new Subject<string>();
// Expose as observable
data$ = this.dataSubject.asObservable();
emitData(data: string) {
this.dataSubject.next(data); // Emit new value
}
}
Component 1 (Subscriber)
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-component1',
template: `<p>Component 1: {{ message }}</p>`,
})
export class Component1 implements OnInit {
message = '';
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.data$.subscribe((data) => {
this.message = data; // React to emitted values
});
}
}
Component 2 (Subscriber)
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-component2',
template: `<p>Component 2: {{ message }}</p>`,
})
export class Component2 implements OnInit {
message = '';
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.data$.subscribe((data) => {
this.message = data; // React to emitted values
});
}
}
Component 3 (Emitting Data)
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-component3',
template: `<button (click)="sendMessage()">Send Message</button>`,
})
export class Component3 {
constructor(private dataService: DataService) {}
sendMessage() {
this.dataService.emitData('Hello from Component 3!');
}
}
Behavior of Subscriptions
When Component3 emits a value (e.g., emitData('Hello!')), all components (Component1, Component2, etc.) subscribed to data$ will immediately receive the value.
Each subscription runs independently, meaning one subscriber's state doesn’t affect others.