0

Whyyyyyyyyyyyyyyy?

Dear Reader,

I've searched high and low, but nobody can explain this without a huge leap of faith to just say, "Here are the effects!", or "This is how you do that! Don't ask why!"

The issue

class ChildComponent {
    @Output selected: EventEmitter<T>() = EventEmitter<T>();
    @Input item;
    handleClick(e, t) {
        ...
        this.selected.emit(t);
    }
}

class ParentComponent {
    items = [];
    handleSelection(type) {
        ...
    }
}

Parent Template

<child-component [item]="item" (selected)="handleSelection(item)" *ngFor="let item of items">
    {{item.name}}
</child-component>

For whatever reason, nobody can explain this syntax in anything remotely abstract. Every answer is so unbearably concrete that any meaning is lost outside of the specificity of defining events at the component level, where only the direct parent has access -- and, there's virtually no reason whatsoever to use @Output/EventEmitter instead of @Input/callback.

Question

@Output isThisAUselessVariable; Given that this "output" is undefined -- moreover, has nothing to do with EventEmitter -- what in Poseidon's sake would I do with this? At this point, what can I even use it for? Is it utterly useless now? What if it has a value, but the value is an Array or an Object? What about a String? How may I use @Output without using EventEmitter?

That seems like odd questioning here, but I want to avoid answers of "Because you can use it for events. If you want an event, use this! This is how you do events! Why??? I don't know! Just remember the magic event syntax!"

Further Questions & Curiosities

A)

Why the nomenclature "@Output"? What makes it an "output"?


B)

Aside from potential benefits of Message Coupling, why not use @Input with callbacks?


C)

Is messaging the only reason why I'd use @Output? What else is/can it be used for? [ SEE 'A' ]


D)

Who can listen for this event? Can a great-grandparent listen without having to pass in a handler directly to the child/great-grandchild and manually bubble it? [ SEE 'B' ]


E)

I'm used to messaging being global or bubbling, and well-designed Event-Driven Architectures to define Event-Types at the Application-Scale -- not the Component-Scale. This allows for different types of "Message Filtering" (SEE Wikipedia), and allows us to use an Application Mediator.

Why would I want to use this at the component scale? How can I define events on a higher scale and use them on a lower scale?


F)

How can I mediate these events? [ SEE 'E' ]


Tons of Appreciation,

Cody

Cody
  • 9,785
  • 4
  • 61
  • 46
  • 3
    “and, there's virtually no reason whatsoever to use `@Output`/`EventEmitter` instead of `@Input`/`callback`” How about all the usual reasons for using events instead of callbacks, e.g. if you need a number of listeners that is not 1? – Ry- Jan 05 '17 at 20:30
  • 2
    Personal recommendation - I'd suggest asking questions instead of making criticisms: *"This is wrong. Why would someone make something wrong?"* won't really motivate anyone to take the time to answer a question, let alone a 6 part question. – chrisbajorin Jan 05 '17 at 20:42
  • 1
    This question is wayyyyyyyyyyyyyyy too broad... – Heretic Monkey Jan 05 '17 at 21:51
  • Also, make your title something other than a bunch of keywords; see [ask]. – Heretic Monkey Jan 05 '17 at 21:52
  • Mike, I think you mean *in-depth*. Broad would be something like, "how do I use TypeScript?", which has a lot of breadth. This question just regards @Output. – Cody Jan 05 '17 at 22:10

1 Answers1

3

If you annotate a variable with @Output it has to be of the type EventEmitter. The name of the variable becomes the name of the custom event. Messaging is the only reason for using @Output. You're sending an event without caring who's interested in getting it. Angular doesn't support event bubbling, but you can implement it with native DOM events.

IMO, using events offers a more loosely coupled architecture in inter-component communication than passing callbacks. In this blog I showed how to use callbacks with @Input params: https://yakovfain.com/2016/10/31/angular-2-component-communication-with-events-vs-callbacks/

In this video I showed one of the ways of mediating using @Input, @Output, and the parent component as a mediator: https://www.youtube.com/watch?v=tSXx4NoKEYY Using an injectable service as a mediator offers more flexibility though.

Yakov Fain
  • 11,972
  • 5
  • 33
  • 38