I have started working on an angular 8 project where two sibling components have to exchange data. So far, the approach was to have an EventEmitter in the parent's service. The child components then called the emit methods on these emitters to pass the data to the other sibling. Here an example case:
Shared Service: (bad)
@Injectable()
export class DocumentViewerService {
public readonly annotationDeletedInAnnotationPanel = new EventEmitter<string>();
Child Component: (bad)
this.documentViewerService.annotationDeletedInAnnotationPanel.emit(annotationId);
However, I found several online sources (1, 2) that claim using EventEmitters in Services is bad practice.
Instead, most online sources (3, 4) propose a pattern using Subjects and shared services for sibling communication.
Shared Service: (good)
@Injectable()
export class DocumentViewerService {
private deletedAnnotationInAnnotationPanel$ = new Subject<string>();
public readonly deletedAnnotationInPanel$ = this.deletedAnnotationInAnnotationPanel$.asObservable();
deleteAnnotationInPanel(annotationId: string) {
this.deletedAnnotationInWebViewer$.next(annotationId);
}
Child Component: (good)
this.documentViewerService.deleteAnnotationInPanel(id);
Both approaches leave me with a few questions:
- Why is it bad practice to use EventEmitters in Service. You don't need to put the @Output tag and it will act similar to an observable when called with emit in one of the childs.
- What's the reason to make the Subject private in the supposedly better approach? Children components can still change the values by calling the provided method deleteAnnotationInPanel (in sample above).
What's the difference in making the Subject deletedAnnotationInAnnotationPanel$ private vs. public readonly. The latter would allow everyone to subscribe and call .next, but not to change initialisation. Instead of five lines of code, I would only have one:
public readonly deletedAnnotationInPanel$ = new Subject();
None of the online sources seem to explain why to make the Subject private with a setter method and an additional public observable for children.
Hopefully, you can provide me with some strong arguments or insights into why one should be preferred over the others. Thanks in advance for the support!