3
  1. Is EventEmitter an RxJS Observable?
  2. In the angular documentation, it explains how to communicate from child to parent component using EventEmitter. Should we use EventEmitter only in component or it can be used angular service also?
  3. In the angular documentation, it explains how parent and children communicate via a shared service that uses observables RxJS Subject. Can we use EventEmitter instead of RxJS Subject in this MissionService example? Please help converting this example with EventEmitter if we can use EventEmitter at all in a service. I'm new to angular.

    https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

I'm confused a bit after reading these related posts:

Jyoti Prasad Pal
  • 1,569
  • 3
  • 26
  • 41
  • Possible duplicate of [Angular 2 Event emitters vs Subject](https://stackoverflow.com/questions/40238549/angular-2-event-emitters-vs-subject) – Estus Flask Sep 01 '17 at 07:39

2 Answers2

1

EventEmiter extends from RxJs subject and you can use it as Observable.

Angular sources

    export declare class EventEmitter<T> extends Subject<T> {
      __isAsync: boolean;
      constructor(isAsync?: boolean);
      emit(value?: T): void;
      subscribe(generatorOrNext?: any, error?: any, complete?: any): any;
    }

The best practice to sharing data between parent and child components use @Input and @Output

When you need to use service for sharing. You need to use Subject or BehaviorSubject

service example

@Injectable()
export class MyService {
  private data: BehaviorSubject<MyData> = new BehaviorSubject(null);

  getData(): Observable<MyData> {
    return this.data;
  }

  setData(d: MyData): void {
    this.data.next(d);
  }
}

use in component

data: Observable<MyData>;

constructor(private myService: MyService) {}

ngOnInit() {
   this.data = this.myService.getData();
}

use in template

<div>{{data|async}}</div>
Kliment Ru
  • 2,057
  • 13
  • 16
  • It is good practice to not use rxjs (including queues) or variables on services setup as global state (initialized in ngModel instead of on the component). Global state is an antipattern/anti-mvvm/mvc. – TamusJRoyce May 19 '21 at 04:44
0

There are many different ways to handle event scenario's.

The EventEmitter is the most common way to communicate child events to the parent. Say you created a child component and clicked a button there, you might want the clicked event in the parent:

<button (click)="clickEmitter.emit()">button</button>

<child-component (clickEmitter)="buttonClicked()"></child-component>

A shared service (Injectable) can be used to store data for multiple components.

A Subject and BehaviorSubject can be used to share events between components (sometimes via the shared service). For example: i used an authService with a user BehaviorSubject inside to get the logged in user object in every component.

These are just some simple examples amongst many other use-cases.

Carsten
  • 4,005
  • 21
  • 28
  • yes. rxjs doesn't have to be done through a service. Often best to avoid storing state, including rxjs message queues on services. Sometimes on services is a good call-out. – TamusJRoyce May 19 '21 at 04:46
  • The html code is not really useful without specifying the component.ts code. Good practice in naming input/outputs are: `@Input() public name: string; @Output() public nameChange = new EventEmitter();` (where data is a public field on the parent component) for two-way binding. It is just a shortcut for if you need additional methods – TamusJRoyce May 19 '21 at 04:47