1

Consider two component c1, c2. I want to transfer some data from c1 to c2. One way I could do it is to create an EventEmitter with @output in c1 and .emit() when need to. Then .subscribe() it at c2 and get the data.

As far as I know using rxjs::Subject is better than using EventEmitter because the last expands the rxjs::Subject. So why would I use @output EventEmitter at all? I could always just use rxjs::Subject..

In which circumstances I would use @output EventEmitter variable?

My Guess: Two cases: 1. Using services: Using Subject instead of EventEmitter due runtime performance. 2. not Using services: Then I have to declare @output. Then, when using @output, EventEmitter is necessary to use. Then use EventEmitter over Subject.

  • Instruction is unclear. What are relations between those component? Are they siblings? Or maybe a parent with a child? How will access rxjs Subject from one component in another component? Can you provide an example? – Ivan Jan 21 '20 at 14:17
  • @Ivan It is unclear on purpose. Because this is the question. In which cases, I would use `@output` over `Subject`? – Qwert Trewq Jan 21 '20 at 14:20
  • @Zircon No. It is not the same Q. The referenced question is about using EventEmitter against subject *only when @output* is involved. – Qwert Trewq Jan 21 '20 at 14:21
  • @QwertTrewq Sorry, I don't follow. You should only use `EventEmitter` when you're using `@Output`, and when using `@Output` you should always use `EventEmitter`. Details about this and the advantages of `EventEmitter` in this case are detailed among answers in the linked question. – Zircon Jan 21 '20 at 14:23
  • @Zircon Yes, you are right. But as known, `subject` is better, in aspects of runtime, than `eventEmitter`. **So why would I use `@output` instead of `subject` from the start?** – Qwert Trewq Jan 21 '20 at 14:28
  • @QwertTrewq I recommend looking at the dupe question and its linked reference. The main benefits: `EventEmitter` is a `Subject` that is automatically closed by Angular while also having functions that help ensure the dev does not misuse it. – Zircon Jan 21 '20 at 14:37
  • @Zircon I edited my Q. – Qwert Trewq Jan 21 '20 at 14:44
  • @QwertTrewq Thanks, I think I understand your question. Check out this answer for when to use `EventEmitter` https://stackoverflow.com/a/52127045/4793951 (summarized: Child to parent only). For the Angular way to handle all types of component interaction check out the official guide: https://angular.io/guide/component-interaction (each use case varies based on the relationship between components) – Zircon Jan 21 '20 at 14:50
  • @QwertTrewq and still... it's very clear how you can use EventEmitter. But there is no clear way you can use just a subject you need a service for it. You updated you question and now it's pretty clear. – Ivan Jan 23 '20 at 09:53

2 Answers2

1

Consider two component c1, c2. I want to transfer some data from c1 to c2. One way I could do it is to create an EventEmitter with @output in c1 and .emit() when need to. Then .subscribe() it at c2 and get the data.

It's not the typical use of outputs in Angular. Usually you'll have a parent component consuming its child's output, like this:

<app-child-component (click)="handleClick($event)"></app-child-component>

Or, maybe a more complex case:

<app-child-component *ngFor="let item of items; let i = index" [someParameter]="item.name" (click)="handleClick($event, i)"></app-child-component>

...

handleClick = (what: Item, whichOne: number) => { //...

Doing the same with subjects, explicit subscriptions, explicit cleanup, should be doable, but would probably result in longer, uglier code.

mbojko
  • 13,503
  • 1
  • 16
  • 26
  • But in other aspect, run time of application would be better with `Subject` than `@output eventEmitter` because of the fact that `eventEmitter` expands `Subject`. So - is it all about uglier code VS run time considerations? – Qwert Trewq Jan 21 '20 at 14:26
  • Can you provide actual benchmarks to confirm the performance loss? How significant is it? – mbojko Jan 21 '20 at 14:28
  • Well, `eventEmitter` expands `Subject`.. So why wouldn't it be performance loss? – Qwert Trewq Jan 21 '20 at 14:30
  • Because it transpiles to the same thing anyway? I don't know. I haven't tested it. Have you? The point is: assuming that you lose performance simply because the `extends` keyword appears in the source code is unwarranted. – mbojko Jan 21 '20 at 14:34
  • I think I found where I was wrong. I forgot that, in case you don't use service - **You have to declare an `@output` to transform the data to `c2`**. So basically always use `Subject` when Using Services? – Qwert Trewq Jan 21 '20 at 14:38
-1

Why do you say Subject is better than EventEmitter? EventEmitter is a subject that can emit synchronously or asynchronously the message....

It looks better to use EventEmitter with @output... Otherwise, you have to have a reference of your emitter on the parent... then subscribe manually to it...

(emitter)="doSomething($event)" looks more simple and elegant

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61