Anton Gildebrand Anton Gildebrand - 1 month ago 16
TypeScript Question

Angular2 why use @Output over @Input for callbacks

I am learning Angular2, after working with Angular1 for a couple of years. I'm creating a credit card form component, with the main goal to learn a couple of key concepts in Angular2. The component should handle all formatting, and return a Stripe token through a callback. I realised that I can handle callbacks in two ways.

Using an @Output parameter

In my component I define a output variable and use it like in this example:

export class CreditCardForm{
....
@Output () callback = new EventEmitter();
....

doCallback(){
this.callback.emit({data: 123});
}
}

// Parent view
<credit-card-form (callback)="creditCardCallback($event)"></credit-card-form>


Using an @Input variable

However, I could just pass the callback method (
creditCardCallback
, used in the parent template) to an input variable, like this:

export class CreditCardForm{
....
@Input () callback;
....

doCallback(){
this.callback({data: 123});
}
}

// Parent view
<credit-card-form [callback]="creditCardCallback"></credit-card-form>


The question

Why would I want to use
@Output
over
@Input
? What do I achieve by using
@Output
variables instead? As far as I can see, this just adds an overhead by having to utilise the
EventEmitter
class.

Answer

There are always more than one way to skin the cat. However, in my opinion, using @Output has these benefits:

  • Code readability: It's easier to know the flow of data if using the recommended style.

  • De-coupling: For example, for normal @Output event, in your ParentComponent, you can have more flexibility of handling the dispatched event:

  • Last but not least - it enables banana in the box syntax: Say in your ChildComponent you have:

@Input() creditCardValue: string; @Output() creditCardValueChange: EventEmitter<string>;

Then you can have two-way binding in your ParentComponent easily:

<credit-card-form [(creditCardValue)]="creditCardVal"></credit-card-form>